@ikenxuan/amagi 5.5.1 → 5.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/default/cjs/index.cjs +253 -49
- package/dist/default/esm/index.mjs +251 -48
- package/dist/default/index.d.ts +6 -0
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var chalk = require('chalk');
|
|
6
6
|
var log4js = require('log4js');
|
|
7
7
|
var path = require('path');
|
|
8
|
-
var
|
|
8
|
+
var URL2 = require('url');
|
|
9
9
|
var fs = require('fs');
|
|
10
10
|
var axios = require('axios');
|
|
11
11
|
var crypto = require('crypto');
|
|
@@ -17,6 +17,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
17
17
|
|
|
18
18
|
var log4js__default = /*#__PURE__*/_interopDefault(log4js);
|
|
19
19
|
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
20
|
+
var URL2__default = /*#__PURE__*/_interopDefault(URL2);
|
|
20
21
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
21
22
|
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
22
23
|
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
@@ -33,7 +34,7 @@ var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${_
|
|
|
33
34
|
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
34
35
|
var getPackageLogsPath = () => {
|
|
35
36
|
const currentFileUrl = importMetaUrl;
|
|
36
|
-
const currentFilePath =
|
|
37
|
+
const currentFilePath = URL2.fileURLToPath(currentFileUrl);
|
|
37
38
|
const currentDir = path__default.default.dirname(currentFilePath);
|
|
38
39
|
let packageRoot = currentDir;
|
|
39
40
|
while (packageRoot !== path__default.default.dirname(packageRoot)) {
|
|
@@ -1332,6 +1333,184 @@ var a_bogus_default = (url, user_agent) => {
|
|
|
1332
1333
|
let result_str = generate_random_str() + generate_rc4_bb_str(new URLSearchParams(new URL(url).search).toString(), cleanedUserAgent, "1536|747|1536|834|0|30|0|0|1536|834|1536|864|1525|747|24|24|Win32");
|
|
1333
1334
|
return result_encrypt(result_str, "s4") + "=";
|
|
1334
1335
|
};
|
|
1336
|
+
var XBogus = class {
|
|
1337
|
+
charMap;
|
|
1338
|
+
base64Charset;
|
|
1339
|
+
uaKey;
|
|
1340
|
+
defaultUa;
|
|
1341
|
+
params;
|
|
1342
|
+
xb;
|
|
1343
|
+
constructor() {
|
|
1344
|
+
this.charMap = new Array(128).fill(null);
|
|
1345
|
+
for (let i = 48; i <= 57; i++) {
|
|
1346
|
+
this.charMap[i] = i - 48;
|
|
1347
|
+
}
|
|
1348
|
+
for (let i = 65; i <= 70; i++) {
|
|
1349
|
+
this.charMap[i] = i - 55;
|
|
1350
|
+
}
|
|
1351
|
+
for (let i = 97; i <= 102; i++) {
|
|
1352
|
+
this.charMap[i] = i - 87;
|
|
1353
|
+
}
|
|
1354
|
+
this.base64Charset = "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=";
|
|
1355
|
+
this.uaKey = Buffer.from([0, 1, 12]);
|
|
1356
|
+
this.defaultUa = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0";
|
|
1357
|
+
}
|
|
1358
|
+
md5StrToArray(md5Str) {
|
|
1359
|
+
const result = [];
|
|
1360
|
+
if (md5Str.length > 32) {
|
|
1361
|
+
for (const char of md5Str) {
|
|
1362
|
+
result.push(char.charCodeAt(0));
|
|
1363
|
+
}
|
|
1364
|
+
return result;
|
|
1365
|
+
}
|
|
1366
|
+
let idx = 0;
|
|
1367
|
+
while (idx < md5Str.length) {
|
|
1368
|
+
const leftCharCode = md5Str.charCodeAt(idx);
|
|
1369
|
+
const rightCharCode = md5Str.charCodeAt(idx + 1);
|
|
1370
|
+
const left = this.charMap[leftCharCode];
|
|
1371
|
+
const right = this.charMap[rightCharCode];
|
|
1372
|
+
if (left === null || right === null) {
|
|
1373
|
+
throw new Error(`Invalid MD5 character: ${md5Str[idx]}${md5Str[idx + 1]}`);
|
|
1374
|
+
}
|
|
1375
|
+
result.push(left << 4 | right);
|
|
1376
|
+
idx += 2;
|
|
1377
|
+
}
|
|
1378
|
+
return result;
|
|
1379
|
+
}
|
|
1380
|
+
md5(input) {
|
|
1381
|
+
const dataArray = typeof input === "string" ? this.md5StrToArray(input) : input;
|
|
1382
|
+
const dataBuffer = Buffer.from(dataArray);
|
|
1383
|
+
return crypto__default.default.createHash("md5").update(dataBuffer).digest("hex");
|
|
1384
|
+
}
|
|
1385
|
+
md5Encrypt(urlPath) {
|
|
1386
|
+
const firstMd5 = this.md5(urlPath);
|
|
1387
|
+
const firstArray = this.md5StrToArray(firstMd5);
|
|
1388
|
+
const secondMd5 = this.md5(firstArray);
|
|
1389
|
+
return this.md5StrToArray(secondMd5);
|
|
1390
|
+
}
|
|
1391
|
+
encodingConversion(...params) {
|
|
1392
|
+
const byteList = [];
|
|
1393
|
+
for (const param of params) {
|
|
1394
|
+
if (typeof param === "number") {
|
|
1395
|
+
byteList.push(Math.floor(param));
|
|
1396
|
+
} else if (typeof param === "string") {
|
|
1397
|
+
for (const char of param) {
|
|
1398
|
+
byteList.push(char.charCodeAt(0));
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
return Buffer.from(byteList).toString("latin1");
|
|
1403
|
+
}
|
|
1404
|
+
encodingConversion2(a, b, c) {
|
|
1405
|
+
return String.fromCharCode(a) + String.fromCharCode(b) + c;
|
|
1406
|
+
}
|
|
1407
|
+
rc4Encrypt(key, data2) {
|
|
1408
|
+
const keyBuffer = typeof key === "string" ? Buffer.from(key, "latin1") : key;
|
|
1409
|
+
const dataBuffer = Buffer.from(data2, "latin1");
|
|
1410
|
+
const S = Array.from({ length: 256 }, (_, i2) => i2);
|
|
1411
|
+
let j = 0;
|
|
1412
|
+
for (let i2 = 0; i2 < 256; i2++) {
|
|
1413
|
+
j = (j + S[i2] + keyBuffer[i2 % keyBuffer.length]) % 256;
|
|
1414
|
+
[S[i2], S[j]] = [S[j], S[i2]];
|
|
1415
|
+
}
|
|
1416
|
+
const encryptedBuffer = Buffer.alloc(dataBuffer.length);
|
|
1417
|
+
let i = 0;
|
|
1418
|
+
j = 0;
|
|
1419
|
+
for (let k = 0; k < dataBuffer.length; k++) {
|
|
1420
|
+
i = (i + 1) % 256;
|
|
1421
|
+
j = (j + S[i]) % 256;
|
|
1422
|
+
[S[i], S[j]] = [S[j], S[i]];
|
|
1423
|
+
const t = (S[i] + S[j]) % 256;
|
|
1424
|
+
encryptedBuffer[k] = dataBuffer[k] ^ S[t];
|
|
1425
|
+
}
|
|
1426
|
+
return encryptedBuffer.toString("latin1");
|
|
1427
|
+
}
|
|
1428
|
+
calculation(a1, a2, a3) {
|
|
1429
|
+
const x1 = (a1 & 255) << 16;
|
|
1430
|
+
const x2 = (a2 & 255) << 8;
|
|
1431
|
+
const x3 = x1 | x2 | a3 & 255;
|
|
1432
|
+
const c1 = this.base64Charset[(x3 & 16760832) >> 18];
|
|
1433
|
+
const c2 = this.base64Charset[(x3 & 258048) >> 12];
|
|
1434
|
+
const c3 = this.base64Charset[(x3 & 4032) >> 6];
|
|
1435
|
+
const c4 = this.base64Charset[x3 & 63];
|
|
1436
|
+
return c1 + c2 + c3 + c4;
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
* 生成X-Bogus签名
|
|
1440
|
+
* @param url 完整的URL地址
|
|
1441
|
+
* @param ua 可选的User-Agent,不提供则使用默认值
|
|
1442
|
+
* @returns 包含完整URL、X-Bogus值和使用的User-Agent的元组
|
|
1443
|
+
*/
|
|
1444
|
+
getXBogus(url, ua) {
|
|
1445
|
+
const parsedUrl = new URL2__default.default.URL(url);
|
|
1446
|
+
const urlPath = parsedUrl.pathname + parsedUrl.search;
|
|
1447
|
+
const currentUa = ua || this.defaultUa;
|
|
1448
|
+
const rc4EncryptedUa = this.rc4Encrypt(this.uaKey, currentUa);
|
|
1449
|
+
const base64Ua = Buffer.from(rc4EncryptedUa, "latin1").toString("base64");
|
|
1450
|
+
const md5Ua = this.md5(base64Ua);
|
|
1451
|
+
const array1 = this.md5StrToArray(md5Ua);
|
|
1452
|
+
const emptyStrMd5 = "d41d8cd98f00b204e9800998ecf8427e";
|
|
1453
|
+
const array2 = this.md5StrToArray(this.md5(this.md5StrToArray(emptyStrMd5)));
|
|
1454
|
+
const urlEncryptedArray = this.md5Encrypt(urlPath);
|
|
1455
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
1456
|
+
const ct = 536919696;
|
|
1457
|
+
const newArray = [
|
|
1458
|
+
64,
|
|
1459
|
+
1,
|
|
1460
|
+
1,
|
|
1461
|
+
12,
|
|
1462
|
+
urlEncryptedArray[14],
|
|
1463
|
+
urlEncryptedArray[15],
|
|
1464
|
+
array2[14],
|
|
1465
|
+
array2[15],
|
|
1466
|
+
array1[14],
|
|
1467
|
+
array1[15],
|
|
1468
|
+
timestamp >> 24 & 255,
|
|
1469
|
+
timestamp >> 16 & 255,
|
|
1470
|
+
timestamp >> 8 & 255,
|
|
1471
|
+
timestamp & 255,
|
|
1472
|
+
ct >> 24 & 255,
|
|
1473
|
+
ct >> 16 & 255,
|
|
1474
|
+
ct >> 8 & 255,
|
|
1475
|
+
ct & 255
|
|
1476
|
+
];
|
|
1477
|
+
let xorResult = newArray[0];
|
|
1478
|
+
for (let i = 1; i < newArray.length; i++) {
|
|
1479
|
+
xorResult ^= newArray[i];
|
|
1480
|
+
}
|
|
1481
|
+
newArray.push(xorResult);
|
|
1482
|
+
const array3 = [];
|
|
1483
|
+
const array4 = [];
|
|
1484
|
+
let idx = 0;
|
|
1485
|
+
while (idx < newArray.length) {
|
|
1486
|
+
array3.push(newArray[idx]);
|
|
1487
|
+
if (idx + 1 < newArray.length) {
|
|
1488
|
+
array4.push(newArray[idx + 1]);
|
|
1489
|
+
}
|
|
1490
|
+
idx += 2;
|
|
1491
|
+
}
|
|
1492
|
+
const mergedArray = [...array3, ...array4];
|
|
1493
|
+
const firstConversion = this.encodingConversion(...mergedArray);
|
|
1494
|
+
const rc4Garbled = this.rc4Encrypt("\xFF", firstConversion);
|
|
1495
|
+
const garbledCode = this.encodingConversion2(2, 255, rc4Garbled);
|
|
1496
|
+
let xb = "";
|
|
1497
|
+
idx = 0;
|
|
1498
|
+
while (idx < garbledCode.length) {
|
|
1499
|
+
if (idx + 2 >= garbledCode.length) break;
|
|
1500
|
+
const a1 = garbledCode.charCodeAt(idx);
|
|
1501
|
+
const a2 = garbledCode.charCodeAt(idx + 1);
|
|
1502
|
+
const a3 = garbledCode.charCodeAt(idx + 2);
|
|
1503
|
+
xb += this.calculation(a1, a2, a3);
|
|
1504
|
+
idx += 3;
|
|
1505
|
+
}
|
|
1506
|
+
const fullUrl = url.includes("?") ? `${url}&X-Bogus=${xb}` : `${url}?X-Bogus=${xb}`;
|
|
1507
|
+
return {
|
|
1508
|
+
fullUrl,
|
|
1509
|
+
xbogus: xb,
|
|
1510
|
+
userAgent: currentUa
|
|
1511
|
+
};
|
|
1512
|
+
}
|
|
1513
|
+
};
|
|
1335
1514
|
|
|
1336
1515
|
// src/platform/douyin/sign/index.ts
|
|
1337
1516
|
var defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36";
|
|
@@ -1354,6 +1533,15 @@ var douyinSign = class {
|
|
|
1354
1533
|
static AB(url, userAgent) {
|
|
1355
1534
|
return a_bogus_default(url, userAgent || defaultUserAgent);
|
|
1356
1535
|
}
|
|
1536
|
+
/**
|
|
1537
|
+
* X-Bogus 签名算法
|
|
1538
|
+
* @param url 需要签名的地址
|
|
1539
|
+
* @returns 对此地址签名后的URL查询参数
|
|
1540
|
+
*/
|
|
1541
|
+
static XB(url, userAgent) {
|
|
1542
|
+
const xbogusResult = new XBogus().getXBogus(url, userAgent || defaultUserAgent);
|
|
1543
|
+
return xbogusResult.xbogus;
|
|
1544
|
+
}
|
|
1357
1545
|
/** 生成一个唯一的验证字符串 */
|
|
1358
1546
|
static VerifyFpManager() {
|
|
1359
1547
|
const e = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
|
|
@@ -1482,7 +1670,7 @@ var DouyinAPI = class {
|
|
|
1482
1670
|
* @returns 完整的接口URL
|
|
1483
1671
|
*/
|
|
1484
1672
|
\u4E8C\u7EA7\u8BC4\u8BBA(data2) {
|
|
1485
|
-
const baseUrl = "https://www.douyin.com/aweme/v1/web/comment/list/reply/";
|
|
1673
|
+
const baseUrl = "https://www-hj.douyin.com/aweme/v1/web/comment/list/reply/";
|
|
1486
1674
|
const params = {
|
|
1487
1675
|
device_platform: "webapp",
|
|
1488
1676
|
aid: "6383",
|
|
@@ -1506,10 +1694,10 @@ var DouyinAPI = class {
|
|
|
1506
1694
|
browser_language: "zh-CN",
|
|
1507
1695
|
browser_platform: "Win32",
|
|
1508
1696
|
browser_name: "Edge",
|
|
1509
|
-
browser_version:
|
|
1697
|
+
browser_version: this.browserVersion,
|
|
1510
1698
|
browser_online: "true",
|
|
1511
1699
|
engine_name: "Blink",
|
|
1512
|
-
engine_version:
|
|
1700
|
+
engine_version: this.browserVersion,
|
|
1513
1701
|
os_name: "Windows",
|
|
1514
1702
|
os_version: "10",
|
|
1515
1703
|
cpu_core_num: "16",
|
|
@@ -1518,7 +1706,7 @@ var DouyinAPI = class {
|
|
|
1518
1706
|
downlink: "10",
|
|
1519
1707
|
effective_type: "4g",
|
|
1520
1708
|
round_trip_time: "50",
|
|
1521
|
-
webid: "
|
|
1709
|
+
webid: "7487210762873685515",
|
|
1522
1710
|
verifyFp: fp,
|
|
1523
1711
|
fp
|
|
1524
1712
|
};
|
|
@@ -1822,6 +2010,29 @@ var createDouyinApiUrls = (userAgent) => {
|
|
|
1822
2010
|
var douyinApiUrls = new DouyinAPI();
|
|
1823
2011
|
|
|
1824
2012
|
// src/platform/douyin/getdata.ts
|
|
2013
|
+
var getSignature = (url, signType = "a_bogus", userAgent) => {
|
|
2014
|
+
switch (signType) {
|
|
2015
|
+
case "x_bogus":
|
|
2016
|
+
return douyinSign.XB(url, userAgent);
|
|
2017
|
+
case "a_bogus":
|
|
2018
|
+
default:
|
|
2019
|
+
return douyinSign.AB(url, userAgent);
|
|
2020
|
+
}
|
|
2021
|
+
};
|
|
2022
|
+
var getSignParamName = (signType = "a_bogus") => {
|
|
2023
|
+
switch (signType) {
|
|
2024
|
+
case "x_bogus":
|
|
2025
|
+
return "X-Bogus";
|
|
2026
|
+
case "a_bogus":
|
|
2027
|
+
default:
|
|
2028
|
+
return "a_bogus";
|
|
2029
|
+
}
|
|
2030
|
+
};
|
|
2031
|
+
var buildSignedUrl = (url, signType = "a_bogus", userAgent) => {
|
|
2032
|
+
const signature = getSignature(url, signType, userAgent);
|
|
2033
|
+
const paramName = getSignParamName(signType);
|
|
2034
|
+
return `${url}&${paramName}=${signature}`;
|
|
2035
|
+
};
|
|
1825
2036
|
var DouyinData = async (data2, cookie, requestConfig) => {
|
|
1826
2037
|
var _a, _b, _c, _d, _e;
|
|
1827
2038
|
const defHeaders = getDouyinDefaultConfig(cookie)["headers"];
|
|
@@ -1835,54 +2046,47 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1835
2046
|
}
|
|
1836
2047
|
};
|
|
1837
2048
|
const userAgent = (_a = baseRequestConfig.headers) == null ? void 0 : _a["User-Agent"];
|
|
1838
|
-
const
|
|
2049
|
+
const douyinApiUrls2 = createDouyinApiUrls(userAgent);
|
|
2050
|
+
const signType = data2.signType || "a_bogus";
|
|
1839
2051
|
switch (data2.methodType) {
|
|
1840
2052
|
case "\u6587\u5B57\u4F5C\u54C1\u6570\u636E":
|
|
1841
2053
|
case "\u805A\u5408\u89E3\u6790":
|
|
1842
2054
|
case "\u89C6\u9891\u4F5C\u54C1\u6570\u636E":
|
|
1843
2055
|
case "\u56FE\u96C6\u4F5C\u54C1\u6570\u636E":
|
|
1844
2056
|
case "\u5408\u8F91\u4F5C\u54C1\u6570\u636E": {
|
|
1845
|
-
const url =
|
|
2057
|
+
const url = douyinApiUrls2.\u89C6\u9891\u6216\u56FE\u96C6({ aweme_id: data2.aweme_id });
|
|
1846
2058
|
const VideoData = await GlobalGetData2(data2.methodType, {
|
|
1847
2059
|
...baseRequestConfig,
|
|
1848
|
-
url:
|
|
2060
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1849
2061
|
});
|
|
1850
2062
|
return VideoData;
|
|
1851
2063
|
}
|
|
1852
2064
|
case "\u8BC4\u8BBA\u6570\u636E": {
|
|
1853
|
-
const urlGenerator = (params) =>
|
|
2065
|
+
const urlGenerator = (params) => douyinApiUrls2.\u8BC4\u8BBA(params);
|
|
1854
2066
|
const response = await fetchPaginatedData(
|
|
1855
2067
|
data2.methodType,
|
|
1856
2068
|
urlGenerator,
|
|
1857
2069
|
data2,
|
|
1858
2070
|
50,
|
|
1859
|
-
baseRequestConfig
|
|
2071
|
+
baseRequestConfig,
|
|
2072
|
+
signType
|
|
1860
2073
|
);
|
|
1861
2074
|
return response;
|
|
1862
2075
|
}
|
|
1863
2076
|
case "\u6307\u5B9A\u8BC4\u8BBA\u56DE\u590D\u6570\u636E": {
|
|
1864
|
-
const urlGenerator = (params) =>
|
|
1865
|
-
const customConfig = {
|
|
1866
|
-
...baseRequestConfig,
|
|
1867
|
-
headers: {
|
|
1868
|
-
...baseRequestConfig.headers,
|
|
1869
|
-
// 只有在外部配置没有referer时才设置内部的referer
|
|
1870
|
-
...(!(requestConfig == null ? void 0 : requestConfig.headers) || !("referer" in requestConfig.headers)) && {
|
|
1871
|
-
referer: `https://www.douyin.com/note/${data2.aweme_id}`
|
|
1872
|
-
}
|
|
1873
|
-
}
|
|
1874
|
-
};
|
|
2077
|
+
const urlGenerator = (params) => douyinApiUrls2.\u4E8C\u7EA7\u8BC4\u8BBA(params);
|
|
1875
2078
|
const response = await fetchPaginatedData(
|
|
1876
2079
|
data2.methodType,
|
|
1877
2080
|
urlGenerator,
|
|
1878
2081
|
data2,
|
|
1879
2082
|
3,
|
|
1880
|
-
|
|
2083
|
+
baseRequestConfig,
|
|
2084
|
+
"x_bogus"
|
|
1881
2085
|
);
|
|
1882
2086
|
return response;
|
|
1883
2087
|
}
|
|
1884
2088
|
case "\u7528\u6237\u4E3B\u9875\u6570\u636E": {
|
|
1885
|
-
const url =
|
|
2089
|
+
const url = douyinApiUrls2.\u7528\u6237\u4E3B\u9875\u4FE1\u606F({ sec_uid: data2.sec_uid });
|
|
1886
2090
|
const customConfig = {
|
|
1887
2091
|
...baseRequestConfig,
|
|
1888
2092
|
headers: {
|
|
@@ -1895,12 +2099,12 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1895
2099
|
};
|
|
1896
2100
|
const UserInfoData = await GlobalGetData2(data2.methodType, {
|
|
1897
2101
|
...customConfig,
|
|
1898
|
-
url:
|
|
2102
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1899
2103
|
});
|
|
1900
2104
|
return UserInfoData;
|
|
1901
2105
|
}
|
|
1902
2106
|
case "Emoji\u6570\u636E": {
|
|
1903
|
-
const url =
|
|
2107
|
+
const url = douyinApiUrls2.\u8868\u60C5();
|
|
1904
2108
|
const EmojiData = await GlobalGetData2(data2.methodType, {
|
|
1905
2109
|
...baseRequestConfig,
|
|
1906
2110
|
url
|
|
@@ -1908,7 +2112,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1908
2112
|
return EmojiData;
|
|
1909
2113
|
}
|
|
1910
2114
|
case "\u7528\u6237\u4E3B\u9875\u89C6\u9891\u5217\u8868\u6570\u636E": {
|
|
1911
|
-
const url =
|
|
2115
|
+
const url = douyinApiUrls2.\u7528\u6237\u4E3B\u9875\u89C6\u9891({ sec_uid: data2.sec_uid });
|
|
1912
2116
|
const customConfig = {
|
|
1913
2117
|
...baseRequestConfig,
|
|
1914
2118
|
headers: {
|
|
@@ -1920,12 +2124,12 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1920
2124
|
};
|
|
1921
2125
|
const UserVideoListData = await GlobalGetData2(data2.methodType, {
|
|
1922
2126
|
...customConfig,
|
|
1923
|
-
url:
|
|
2127
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1924
2128
|
});
|
|
1925
2129
|
return UserVideoListData;
|
|
1926
2130
|
}
|
|
1927
2131
|
case "\u70ED\u70B9\u8BCD\u6570\u636E": {
|
|
1928
|
-
const url =
|
|
2132
|
+
const url = douyinApiUrls2.\u70ED\u70B9\u8BCD({ query: data2.query, number: data2.number ?? 10 });
|
|
1929
2133
|
const customConfig = {
|
|
1930
2134
|
...baseRequestConfig,
|
|
1931
2135
|
headers: {
|
|
@@ -1937,7 +2141,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1937
2141
|
};
|
|
1938
2142
|
const SuggestWordsData = await GlobalGetData2(data2.methodType, {
|
|
1939
2143
|
...customConfig,
|
|
1940
|
-
url:
|
|
2144
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1941
2145
|
});
|
|
1942
2146
|
return SuggestWordsData;
|
|
1943
2147
|
}
|
|
@@ -1957,14 +2161,14 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1957
2161
|
};
|
|
1958
2162
|
while (fetchedSearchList.length < Number(data2.number ?? 10)) {
|
|
1959
2163
|
const requestCount = Math.min(Number(data2.number ?? 50) - fetchedSearchList.length, maxPageSize);
|
|
1960
|
-
const url =
|
|
2164
|
+
const url = douyinApiUrls2.\u641C\u7D22({
|
|
1961
2165
|
query: data2.query,
|
|
1962
2166
|
number: requestCount,
|
|
1963
2167
|
search_id: search_id === "" ? void 0 : search_id
|
|
1964
2168
|
});
|
|
1965
2169
|
const response = await GlobalGetData2(data2.methodType, {
|
|
1966
2170
|
...customConfig,
|
|
1967
|
-
url:
|
|
2171
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1968
2172
|
});
|
|
1969
2173
|
if (((_b = response.data) == null ? void 0 : _b.length) === 0) {
|
|
1970
2174
|
logger.warn("\u83B7\u53D6\u641C\u7D22\u6570\u636E\u5931\u8D25\uFF01\u8BF7\u6C42\u6210\u529F\u4F46\u63A5\u53E3\u8FD4\u56DE\u5185\u5BB9\u4E3A\u7A7A\n\u4F60\u7684\u6296\u97F3ck\u53EF\u80FD\u5DF2\u7ECF\u5931\u6548\uFF01\n\u8BF7\u6C42\u7C7B\u578B\uFF1A" + data2.methodType);
|
|
@@ -1984,24 +2188,24 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1984
2188
|
return finalResponse;
|
|
1985
2189
|
}
|
|
1986
2190
|
case "\u52A8\u6001\u8868\u60C5\u6570\u636E": {
|
|
1987
|
-
const url =
|
|
2191
|
+
const url = douyinApiUrls2.\u4E92\u52A8\u8868\u60C5();
|
|
1988
2192
|
const ExpressionPlusData = await GlobalGetData2(data2.methodType, {
|
|
1989
2193
|
...baseRequestConfig,
|
|
1990
|
-
url:
|
|
2194
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1991
2195
|
});
|
|
1992
2196
|
return ExpressionPlusData;
|
|
1993
2197
|
}
|
|
1994
2198
|
case "\u97F3\u4E50\u6570\u636E": {
|
|
1995
|
-
const url =
|
|
2199
|
+
const url = douyinApiUrls2.\u80CC\u666F\u97F3\u4E50({ music_id: data2.music_id });
|
|
1996
2200
|
const MusicData = await GlobalGetData2(data2.methodType, {
|
|
1997
2201
|
...baseRequestConfig,
|
|
1998
|
-
url:
|
|
2202
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1999
2203
|
});
|
|
2000
2204
|
return MusicData;
|
|
2001
2205
|
}
|
|
2002
2206
|
case "\u76F4\u64AD\u95F4\u4FE1\u606F\u6570\u636E": {
|
|
2003
|
-
let url =
|
|
2004
|
-
const fetchUrl =
|
|
2207
|
+
let url = douyinApiUrls2.\u7528\u6237\u4E3B\u9875\u4FE1\u606F({ sec_uid: data2.sec_uid });
|
|
2208
|
+
const fetchUrl = buildSignedUrl(url, signType, userAgent);
|
|
2005
2209
|
const customConfig = {
|
|
2006
2210
|
...baseRequestConfig,
|
|
2007
2211
|
headers: {
|
|
@@ -2038,7 +2242,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2038
2242
|
};
|
|
2039
2243
|
}
|
|
2040
2244
|
const room_data = JSON.parse(UserInfoData.user.room_data);
|
|
2041
|
-
url =
|
|
2245
|
+
url = douyinApiUrls2.\u76F4\u64AD\u95F4\u4FE1\u606F({ room_id: UserInfoData.user.room_id_str, web_rid: room_data.owner.web_rid });
|
|
2042
2246
|
const liveCustomConfig = {
|
|
2043
2247
|
...baseRequestConfig,
|
|
2044
2248
|
headers: {
|
|
@@ -2050,15 +2254,15 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2050
2254
|
};
|
|
2051
2255
|
const LiveRoomData = await GlobalGetData2(data2.methodType, {
|
|
2052
2256
|
...liveCustomConfig,
|
|
2053
|
-
url:
|
|
2257
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
2054
2258
|
});
|
|
2055
2259
|
return LiveRoomData;
|
|
2056
2260
|
}
|
|
2057
2261
|
case "\u7533\u8BF7\u4E8C\u7EF4\u7801\u6570\u636E": {
|
|
2058
|
-
const url =
|
|
2262
|
+
const url = douyinApiUrls2.\u7533\u8BF7\u4E8C\u7EF4\u7801({ verify_fp: data2.verify_fp });
|
|
2059
2263
|
const LoginQrcodeStatusData = await GlobalGetData2(data2.methodType, {
|
|
2060
2264
|
...baseRequestConfig,
|
|
2061
|
-
url:
|
|
2265
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
2062
2266
|
});
|
|
2063
2267
|
return LoginQrcodeStatusData;
|
|
2064
2268
|
}
|
|
@@ -2068,7 +2272,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2068
2272
|
const endTime = data2.end_time ?? data2.duration;
|
|
2069
2273
|
const totalDuration = endTime - startTime;
|
|
2070
2274
|
if (totalDuration <= MAX_SEGMENT_DURATION) {
|
|
2071
|
-
const url =
|
|
2275
|
+
const url = douyinApiUrls2.\u5F39\u5E55({
|
|
2072
2276
|
aweme_id: data2.aweme_id,
|
|
2073
2277
|
start_time: startTime,
|
|
2074
2278
|
end_time: endTime,
|
|
@@ -2076,7 +2280,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2076
2280
|
});
|
|
2077
2281
|
const DanmakuData = await GlobalGetData2(data2.methodType, {
|
|
2078
2282
|
...baseRequestConfig,
|
|
2079
|
-
url:
|
|
2283
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
2080
2284
|
});
|
|
2081
2285
|
return DanmakuData;
|
|
2082
2286
|
}
|
|
@@ -2089,7 +2293,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2089
2293
|
}
|
|
2090
2294
|
logger.debug(`\u5F39\u5E55\u6570\u636E\u9700\u8981\u5206${segments.length}\u6BB5\u83B7\u53D6\uFF0C\u603B\u65F6\u957F\uFF1A${totalDuration}ms`);
|
|
2091
2295
|
const segmentPromises = segments.map(async (segment, index) => {
|
|
2092
|
-
const url =
|
|
2296
|
+
const url = douyinApiUrls2.\u5F39\u5E55({
|
|
2093
2297
|
aweme_id: data2.aweme_id,
|
|
2094
2298
|
start_time: segment.start,
|
|
2095
2299
|
end_time: segment.end,
|
|
@@ -2098,7 +2302,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2098
2302
|
try {
|
|
2099
2303
|
const segmentData = await GlobalGetData2(`${data2.methodType}-\u6BB5${index + 1}`, {
|
|
2100
2304
|
...baseRequestConfig,
|
|
2101
|
-
url:
|
|
2305
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
2102
2306
|
});
|
|
2103
2307
|
logger.debug(`\u5F39\u5E55\u7B2C${index + 1}\u6BB5\u83B7\u53D6\u6210\u529F (${segment.start}ms-${segment.end}ms)`);
|
|
2104
2308
|
return segmentData;
|
|
@@ -2146,7 +2350,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2146
2350
|
}
|
|
2147
2351
|
}
|
|
2148
2352
|
};
|
|
2149
|
-
var fetchPaginatedData = async (type, apiUrlGenerator, params, maxPageSize, requestConfig) => {
|
|
2353
|
+
var fetchPaginatedData = async (type, apiUrlGenerator, params, maxPageSize, requestConfig, signType = "a_bogus") => {
|
|
2150
2354
|
var _a;
|
|
2151
2355
|
let cursor = params.cursor ?? 0;
|
|
2152
2356
|
let fetchedData = [];
|
|
@@ -2161,7 +2365,7 @@ var fetchPaginatedData = async (type, apiUrlGenerator, params, maxPageSize, requ
|
|
|
2161
2365
|
});
|
|
2162
2366
|
const response = await GlobalGetData2(type, {
|
|
2163
2367
|
...requestConfig,
|
|
2164
|
-
url:
|
|
2368
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
2165
2369
|
});
|
|
2166
2370
|
fetchedData.push(...response.comments || response.data || []);
|
|
2167
2371
|
tmpresp = response;
|
|
@@ -2452,7 +2656,7 @@ var DouyinDanmakuParamsSchema = zod.z.object({
|
|
|
2452
2656
|
aweme_id: zod.z.string({ error: "\u89C6\u9891ID\u5FC5\u987B\u662F\u5B57\u7B26\u4E32" }).min(1, { error: "\u89C6\u9891ID\u4E0D\u80FD\u4E3A\u7A7A" }),
|
|
2453
2657
|
start_time: zod.z.coerce.number({ error: "\u5F00\u59CB\u65F6\u95F4\u5FC5\u987B\u662F\u6570\u5B57" }).int({ error: "\u5F00\u59CB\u65F6\u95F4\u5FC5\u987B\u662F\u6574\u6570" }).min(0, { error: "\u5F00\u59CB\u65F6\u95F4\u4E0D\u80FD\u5C0F\u4E8E0" }).optional(),
|
|
2454
2658
|
end_time: zod.z.coerce.number({ error: "\u7ED3\u675F\u65F6\u95F4\u5FC5\u987B\u662F\u6570\u5B57" }).int({ error: "\u7ED3\u675F\u65F6\u95F4\u5FC5\u987B\u662F\u6574\u6570" }).min(0, { error: "\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u5C0F\u4E8E0" }).optional(),
|
|
2455
|
-
duration: zod.z.number({ error: "\u89C6\u9891\u65F6\u957F\u5FC5\u987B\u662F\u6570\u5B57" }).int({ error: "\u89C6\u9891\u65F6\u957F\u5FC5\u987B\u662F\u6574\u6570" }).min(0, { error: "\u89C6\u9891\u65F6\u957F\u4E0D\u80FD\u5C0F\u4E8E0" })
|
|
2659
|
+
duration: zod.z.coerce.number({ error: "\u89C6\u9891\u65F6\u957F\u5FC5\u987B\u662F\u6570\u5B57" }).int({ error: "\u89C6\u9891\u65F6\u957F\u5FC5\u987B\u662F\u6574\u6570" }).min(0, { error: "\u89C6\u9891\u65F6\u957F\u4E0D\u80FD\u5C0F\u4E8E0" })
|
|
2456
2660
|
}).refine(
|
|
2457
2661
|
(data2) => {
|
|
2458
2662
|
if (data2.end_time !== void 0) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Chalk } from 'chalk';
|
|
2
2
|
import log4js from 'log4js';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { fileURLToPath } from 'url';
|
|
4
|
+
import URL2, { fileURLToPath } from 'url';
|
|
5
5
|
import fs from 'fs';
|
|
6
6
|
import axios, { AxiosError } from 'axios';
|
|
7
7
|
import crypto from 'crypto';
|
|
@@ -1316,6 +1316,184 @@ var a_bogus_default = (url, user_agent) => {
|
|
|
1316
1316
|
let result_str = generate_random_str() + generate_rc4_bb_str(new URLSearchParams(new URL(url).search).toString(), cleanedUserAgent, "1536|747|1536|834|0|30|0|0|1536|834|1536|864|1525|747|24|24|Win32");
|
|
1317
1317
|
return result_encrypt(result_str, "s4") + "=";
|
|
1318
1318
|
};
|
|
1319
|
+
var XBogus = class {
|
|
1320
|
+
charMap;
|
|
1321
|
+
base64Charset;
|
|
1322
|
+
uaKey;
|
|
1323
|
+
defaultUa;
|
|
1324
|
+
params;
|
|
1325
|
+
xb;
|
|
1326
|
+
constructor() {
|
|
1327
|
+
this.charMap = new Array(128).fill(null);
|
|
1328
|
+
for (let i = 48; i <= 57; i++) {
|
|
1329
|
+
this.charMap[i] = i - 48;
|
|
1330
|
+
}
|
|
1331
|
+
for (let i = 65; i <= 70; i++) {
|
|
1332
|
+
this.charMap[i] = i - 55;
|
|
1333
|
+
}
|
|
1334
|
+
for (let i = 97; i <= 102; i++) {
|
|
1335
|
+
this.charMap[i] = i - 87;
|
|
1336
|
+
}
|
|
1337
|
+
this.base64Charset = "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=";
|
|
1338
|
+
this.uaKey = Buffer.from([0, 1, 12]);
|
|
1339
|
+
this.defaultUa = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0";
|
|
1340
|
+
}
|
|
1341
|
+
md5StrToArray(md5Str) {
|
|
1342
|
+
const result = [];
|
|
1343
|
+
if (md5Str.length > 32) {
|
|
1344
|
+
for (const char of md5Str) {
|
|
1345
|
+
result.push(char.charCodeAt(0));
|
|
1346
|
+
}
|
|
1347
|
+
return result;
|
|
1348
|
+
}
|
|
1349
|
+
let idx = 0;
|
|
1350
|
+
while (idx < md5Str.length) {
|
|
1351
|
+
const leftCharCode = md5Str.charCodeAt(idx);
|
|
1352
|
+
const rightCharCode = md5Str.charCodeAt(idx + 1);
|
|
1353
|
+
const left = this.charMap[leftCharCode];
|
|
1354
|
+
const right = this.charMap[rightCharCode];
|
|
1355
|
+
if (left === null || right === null) {
|
|
1356
|
+
throw new Error(`Invalid MD5 character: ${md5Str[idx]}${md5Str[idx + 1]}`);
|
|
1357
|
+
}
|
|
1358
|
+
result.push(left << 4 | right);
|
|
1359
|
+
idx += 2;
|
|
1360
|
+
}
|
|
1361
|
+
return result;
|
|
1362
|
+
}
|
|
1363
|
+
md5(input) {
|
|
1364
|
+
const dataArray = typeof input === "string" ? this.md5StrToArray(input) : input;
|
|
1365
|
+
const dataBuffer = Buffer.from(dataArray);
|
|
1366
|
+
return crypto.createHash("md5").update(dataBuffer).digest("hex");
|
|
1367
|
+
}
|
|
1368
|
+
md5Encrypt(urlPath) {
|
|
1369
|
+
const firstMd5 = this.md5(urlPath);
|
|
1370
|
+
const firstArray = this.md5StrToArray(firstMd5);
|
|
1371
|
+
const secondMd5 = this.md5(firstArray);
|
|
1372
|
+
return this.md5StrToArray(secondMd5);
|
|
1373
|
+
}
|
|
1374
|
+
encodingConversion(...params) {
|
|
1375
|
+
const byteList = [];
|
|
1376
|
+
for (const param of params) {
|
|
1377
|
+
if (typeof param === "number") {
|
|
1378
|
+
byteList.push(Math.floor(param));
|
|
1379
|
+
} else if (typeof param === "string") {
|
|
1380
|
+
for (const char of param) {
|
|
1381
|
+
byteList.push(char.charCodeAt(0));
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
return Buffer.from(byteList).toString("latin1");
|
|
1386
|
+
}
|
|
1387
|
+
encodingConversion2(a, b, c) {
|
|
1388
|
+
return String.fromCharCode(a) + String.fromCharCode(b) + c;
|
|
1389
|
+
}
|
|
1390
|
+
rc4Encrypt(key, data2) {
|
|
1391
|
+
const keyBuffer = typeof key === "string" ? Buffer.from(key, "latin1") : key;
|
|
1392
|
+
const dataBuffer = Buffer.from(data2, "latin1");
|
|
1393
|
+
const S = Array.from({ length: 256 }, (_, i2) => i2);
|
|
1394
|
+
let j = 0;
|
|
1395
|
+
for (let i2 = 0; i2 < 256; i2++) {
|
|
1396
|
+
j = (j + S[i2] + keyBuffer[i2 % keyBuffer.length]) % 256;
|
|
1397
|
+
[S[i2], S[j]] = [S[j], S[i2]];
|
|
1398
|
+
}
|
|
1399
|
+
const encryptedBuffer = Buffer.alloc(dataBuffer.length);
|
|
1400
|
+
let i = 0;
|
|
1401
|
+
j = 0;
|
|
1402
|
+
for (let k = 0; k < dataBuffer.length; k++) {
|
|
1403
|
+
i = (i + 1) % 256;
|
|
1404
|
+
j = (j + S[i]) % 256;
|
|
1405
|
+
[S[i], S[j]] = [S[j], S[i]];
|
|
1406
|
+
const t = (S[i] + S[j]) % 256;
|
|
1407
|
+
encryptedBuffer[k] = dataBuffer[k] ^ S[t];
|
|
1408
|
+
}
|
|
1409
|
+
return encryptedBuffer.toString("latin1");
|
|
1410
|
+
}
|
|
1411
|
+
calculation(a1, a2, a3) {
|
|
1412
|
+
const x1 = (a1 & 255) << 16;
|
|
1413
|
+
const x2 = (a2 & 255) << 8;
|
|
1414
|
+
const x3 = x1 | x2 | a3 & 255;
|
|
1415
|
+
const c1 = this.base64Charset[(x3 & 16760832) >> 18];
|
|
1416
|
+
const c2 = this.base64Charset[(x3 & 258048) >> 12];
|
|
1417
|
+
const c3 = this.base64Charset[(x3 & 4032) >> 6];
|
|
1418
|
+
const c4 = this.base64Charset[x3 & 63];
|
|
1419
|
+
return c1 + c2 + c3 + c4;
|
|
1420
|
+
}
|
|
1421
|
+
/**
|
|
1422
|
+
* 生成X-Bogus签名
|
|
1423
|
+
* @param url 完整的URL地址
|
|
1424
|
+
* @param ua 可选的User-Agent,不提供则使用默认值
|
|
1425
|
+
* @returns 包含完整URL、X-Bogus值和使用的User-Agent的元组
|
|
1426
|
+
*/
|
|
1427
|
+
getXBogus(url, ua) {
|
|
1428
|
+
const parsedUrl = new URL2.URL(url);
|
|
1429
|
+
const urlPath = parsedUrl.pathname + parsedUrl.search;
|
|
1430
|
+
const currentUa = ua || this.defaultUa;
|
|
1431
|
+
const rc4EncryptedUa = this.rc4Encrypt(this.uaKey, currentUa);
|
|
1432
|
+
const base64Ua = Buffer.from(rc4EncryptedUa, "latin1").toString("base64");
|
|
1433
|
+
const md5Ua = this.md5(base64Ua);
|
|
1434
|
+
const array1 = this.md5StrToArray(md5Ua);
|
|
1435
|
+
const emptyStrMd5 = "d41d8cd98f00b204e9800998ecf8427e";
|
|
1436
|
+
const array2 = this.md5StrToArray(this.md5(this.md5StrToArray(emptyStrMd5)));
|
|
1437
|
+
const urlEncryptedArray = this.md5Encrypt(urlPath);
|
|
1438
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
1439
|
+
const ct = 536919696;
|
|
1440
|
+
const newArray = [
|
|
1441
|
+
64,
|
|
1442
|
+
1,
|
|
1443
|
+
1,
|
|
1444
|
+
12,
|
|
1445
|
+
urlEncryptedArray[14],
|
|
1446
|
+
urlEncryptedArray[15],
|
|
1447
|
+
array2[14],
|
|
1448
|
+
array2[15],
|
|
1449
|
+
array1[14],
|
|
1450
|
+
array1[15],
|
|
1451
|
+
timestamp >> 24 & 255,
|
|
1452
|
+
timestamp >> 16 & 255,
|
|
1453
|
+
timestamp >> 8 & 255,
|
|
1454
|
+
timestamp & 255,
|
|
1455
|
+
ct >> 24 & 255,
|
|
1456
|
+
ct >> 16 & 255,
|
|
1457
|
+
ct >> 8 & 255,
|
|
1458
|
+
ct & 255
|
|
1459
|
+
];
|
|
1460
|
+
let xorResult = newArray[0];
|
|
1461
|
+
for (let i = 1; i < newArray.length; i++) {
|
|
1462
|
+
xorResult ^= newArray[i];
|
|
1463
|
+
}
|
|
1464
|
+
newArray.push(xorResult);
|
|
1465
|
+
const array3 = [];
|
|
1466
|
+
const array4 = [];
|
|
1467
|
+
let idx = 0;
|
|
1468
|
+
while (idx < newArray.length) {
|
|
1469
|
+
array3.push(newArray[idx]);
|
|
1470
|
+
if (idx + 1 < newArray.length) {
|
|
1471
|
+
array4.push(newArray[idx + 1]);
|
|
1472
|
+
}
|
|
1473
|
+
idx += 2;
|
|
1474
|
+
}
|
|
1475
|
+
const mergedArray = [...array3, ...array4];
|
|
1476
|
+
const firstConversion = this.encodingConversion(...mergedArray);
|
|
1477
|
+
const rc4Garbled = this.rc4Encrypt("\xFF", firstConversion);
|
|
1478
|
+
const garbledCode = this.encodingConversion2(2, 255, rc4Garbled);
|
|
1479
|
+
let xb = "";
|
|
1480
|
+
idx = 0;
|
|
1481
|
+
while (idx < garbledCode.length) {
|
|
1482
|
+
if (idx + 2 >= garbledCode.length) break;
|
|
1483
|
+
const a1 = garbledCode.charCodeAt(idx);
|
|
1484
|
+
const a2 = garbledCode.charCodeAt(idx + 1);
|
|
1485
|
+
const a3 = garbledCode.charCodeAt(idx + 2);
|
|
1486
|
+
xb += this.calculation(a1, a2, a3);
|
|
1487
|
+
idx += 3;
|
|
1488
|
+
}
|
|
1489
|
+
const fullUrl = url.includes("?") ? `${url}&X-Bogus=${xb}` : `${url}?X-Bogus=${xb}`;
|
|
1490
|
+
return {
|
|
1491
|
+
fullUrl,
|
|
1492
|
+
xbogus: xb,
|
|
1493
|
+
userAgent: currentUa
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
};
|
|
1319
1497
|
|
|
1320
1498
|
// src/platform/douyin/sign/index.ts
|
|
1321
1499
|
var defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36";
|
|
@@ -1338,6 +1516,15 @@ var douyinSign = class {
|
|
|
1338
1516
|
static AB(url, userAgent) {
|
|
1339
1517
|
return a_bogus_default(url, userAgent || defaultUserAgent);
|
|
1340
1518
|
}
|
|
1519
|
+
/**
|
|
1520
|
+
* X-Bogus 签名算法
|
|
1521
|
+
* @param url 需要签名的地址
|
|
1522
|
+
* @returns 对此地址签名后的URL查询参数
|
|
1523
|
+
*/
|
|
1524
|
+
static XB(url, userAgent) {
|
|
1525
|
+
const xbogusResult = new XBogus().getXBogus(url, userAgent || defaultUserAgent);
|
|
1526
|
+
return xbogusResult.xbogus;
|
|
1527
|
+
}
|
|
1341
1528
|
/** 生成一个唯一的验证字符串 */
|
|
1342
1529
|
static VerifyFpManager() {
|
|
1343
1530
|
const e = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
|
|
@@ -1466,7 +1653,7 @@ var DouyinAPI = class {
|
|
|
1466
1653
|
* @returns 完整的接口URL
|
|
1467
1654
|
*/
|
|
1468
1655
|
\u4E8C\u7EA7\u8BC4\u8BBA(data2) {
|
|
1469
|
-
const baseUrl = "https://www.douyin.com/aweme/v1/web/comment/list/reply/";
|
|
1656
|
+
const baseUrl = "https://www-hj.douyin.com/aweme/v1/web/comment/list/reply/";
|
|
1470
1657
|
const params = {
|
|
1471
1658
|
device_platform: "webapp",
|
|
1472
1659
|
aid: "6383",
|
|
@@ -1490,10 +1677,10 @@ var DouyinAPI = class {
|
|
|
1490
1677
|
browser_language: "zh-CN",
|
|
1491
1678
|
browser_platform: "Win32",
|
|
1492
1679
|
browser_name: "Edge",
|
|
1493
|
-
browser_version:
|
|
1680
|
+
browser_version: this.browserVersion,
|
|
1494
1681
|
browser_online: "true",
|
|
1495
1682
|
engine_name: "Blink",
|
|
1496
|
-
engine_version:
|
|
1683
|
+
engine_version: this.browserVersion,
|
|
1497
1684
|
os_name: "Windows",
|
|
1498
1685
|
os_version: "10",
|
|
1499
1686
|
cpu_core_num: "16",
|
|
@@ -1502,7 +1689,7 @@ var DouyinAPI = class {
|
|
|
1502
1689
|
downlink: "10",
|
|
1503
1690
|
effective_type: "4g",
|
|
1504
1691
|
round_trip_time: "50",
|
|
1505
|
-
webid: "
|
|
1692
|
+
webid: "7487210762873685515",
|
|
1506
1693
|
verifyFp: fp,
|
|
1507
1694
|
fp
|
|
1508
1695
|
};
|
|
@@ -1806,6 +1993,29 @@ var createDouyinApiUrls = (userAgent) => {
|
|
|
1806
1993
|
var douyinApiUrls = new DouyinAPI();
|
|
1807
1994
|
|
|
1808
1995
|
// src/platform/douyin/getdata.ts
|
|
1996
|
+
var getSignature = (url, signType = "a_bogus", userAgent) => {
|
|
1997
|
+
switch (signType) {
|
|
1998
|
+
case "x_bogus":
|
|
1999
|
+
return douyinSign.XB(url, userAgent);
|
|
2000
|
+
case "a_bogus":
|
|
2001
|
+
default:
|
|
2002
|
+
return douyinSign.AB(url, userAgent);
|
|
2003
|
+
}
|
|
2004
|
+
};
|
|
2005
|
+
var getSignParamName = (signType = "a_bogus") => {
|
|
2006
|
+
switch (signType) {
|
|
2007
|
+
case "x_bogus":
|
|
2008
|
+
return "X-Bogus";
|
|
2009
|
+
case "a_bogus":
|
|
2010
|
+
default:
|
|
2011
|
+
return "a_bogus";
|
|
2012
|
+
}
|
|
2013
|
+
};
|
|
2014
|
+
var buildSignedUrl = (url, signType = "a_bogus", userAgent) => {
|
|
2015
|
+
const signature = getSignature(url, signType, userAgent);
|
|
2016
|
+
const paramName = getSignParamName(signType);
|
|
2017
|
+
return `${url}&${paramName}=${signature}`;
|
|
2018
|
+
};
|
|
1809
2019
|
var DouyinData = async (data2, cookie, requestConfig) => {
|
|
1810
2020
|
var _a, _b, _c, _d, _e;
|
|
1811
2021
|
const defHeaders = getDouyinDefaultConfig(cookie)["headers"];
|
|
@@ -1819,54 +2029,47 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1819
2029
|
}
|
|
1820
2030
|
};
|
|
1821
2031
|
const userAgent = (_a = baseRequestConfig.headers) == null ? void 0 : _a["User-Agent"];
|
|
1822
|
-
const
|
|
2032
|
+
const douyinApiUrls2 = createDouyinApiUrls(userAgent);
|
|
2033
|
+
const signType = data2.signType || "a_bogus";
|
|
1823
2034
|
switch (data2.methodType) {
|
|
1824
2035
|
case "\u6587\u5B57\u4F5C\u54C1\u6570\u636E":
|
|
1825
2036
|
case "\u805A\u5408\u89E3\u6790":
|
|
1826
2037
|
case "\u89C6\u9891\u4F5C\u54C1\u6570\u636E":
|
|
1827
2038
|
case "\u56FE\u96C6\u4F5C\u54C1\u6570\u636E":
|
|
1828
2039
|
case "\u5408\u8F91\u4F5C\u54C1\u6570\u636E": {
|
|
1829
|
-
const url =
|
|
2040
|
+
const url = douyinApiUrls2.\u89C6\u9891\u6216\u56FE\u96C6({ aweme_id: data2.aweme_id });
|
|
1830
2041
|
const VideoData = await GlobalGetData2(data2.methodType, {
|
|
1831
2042
|
...baseRequestConfig,
|
|
1832
|
-
url:
|
|
2043
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1833
2044
|
});
|
|
1834
2045
|
return VideoData;
|
|
1835
2046
|
}
|
|
1836
2047
|
case "\u8BC4\u8BBA\u6570\u636E": {
|
|
1837
|
-
const urlGenerator = (params) =>
|
|
2048
|
+
const urlGenerator = (params) => douyinApiUrls2.\u8BC4\u8BBA(params);
|
|
1838
2049
|
const response = await fetchPaginatedData(
|
|
1839
2050
|
data2.methodType,
|
|
1840
2051
|
urlGenerator,
|
|
1841
2052
|
data2,
|
|
1842
2053
|
50,
|
|
1843
|
-
baseRequestConfig
|
|
2054
|
+
baseRequestConfig,
|
|
2055
|
+
signType
|
|
1844
2056
|
);
|
|
1845
2057
|
return response;
|
|
1846
2058
|
}
|
|
1847
2059
|
case "\u6307\u5B9A\u8BC4\u8BBA\u56DE\u590D\u6570\u636E": {
|
|
1848
|
-
const urlGenerator = (params) =>
|
|
1849
|
-
const customConfig = {
|
|
1850
|
-
...baseRequestConfig,
|
|
1851
|
-
headers: {
|
|
1852
|
-
...baseRequestConfig.headers,
|
|
1853
|
-
// 只有在外部配置没有referer时才设置内部的referer
|
|
1854
|
-
...(!(requestConfig == null ? void 0 : requestConfig.headers) || !("referer" in requestConfig.headers)) && {
|
|
1855
|
-
referer: `https://www.douyin.com/note/${data2.aweme_id}`
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
};
|
|
2060
|
+
const urlGenerator = (params) => douyinApiUrls2.\u4E8C\u7EA7\u8BC4\u8BBA(params);
|
|
1859
2061
|
const response = await fetchPaginatedData(
|
|
1860
2062
|
data2.methodType,
|
|
1861
2063
|
urlGenerator,
|
|
1862
2064
|
data2,
|
|
1863
2065
|
3,
|
|
1864
|
-
|
|
2066
|
+
baseRequestConfig,
|
|
2067
|
+
"x_bogus"
|
|
1865
2068
|
);
|
|
1866
2069
|
return response;
|
|
1867
2070
|
}
|
|
1868
2071
|
case "\u7528\u6237\u4E3B\u9875\u6570\u636E": {
|
|
1869
|
-
const url =
|
|
2072
|
+
const url = douyinApiUrls2.\u7528\u6237\u4E3B\u9875\u4FE1\u606F({ sec_uid: data2.sec_uid });
|
|
1870
2073
|
const customConfig = {
|
|
1871
2074
|
...baseRequestConfig,
|
|
1872
2075
|
headers: {
|
|
@@ -1879,12 +2082,12 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1879
2082
|
};
|
|
1880
2083
|
const UserInfoData = await GlobalGetData2(data2.methodType, {
|
|
1881
2084
|
...customConfig,
|
|
1882
|
-
url:
|
|
2085
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1883
2086
|
});
|
|
1884
2087
|
return UserInfoData;
|
|
1885
2088
|
}
|
|
1886
2089
|
case "Emoji\u6570\u636E": {
|
|
1887
|
-
const url =
|
|
2090
|
+
const url = douyinApiUrls2.\u8868\u60C5();
|
|
1888
2091
|
const EmojiData = await GlobalGetData2(data2.methodType, {
|
|
1889
2092
|
...baseRequestConfig,
|
|
1890
2093
|
url
|
|
@@ -1892,7 +2095,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1892
2095
|
return EmojiData;
|
|
1893
2096
|
}
|
|
1894
2097
|
case "\u7528\u6237\u4E3B\u9875\u89C6\u9891\u5217\u8868\u6570\u636E": {
|
|
1895
|
-
const url =
|
|
2098
|
+
const url = douyinApiUrls2.\u7528\u6237\u4E3B\u9875\u89C6\u9891({ sec_uid: data2.sec_uid });
|
|
1896
2099
|
const customConfig = {
|
|
1897
2100
|
...baseRequestConfig,
|
|
1898
2101
|
headers: {
|
|
@@ -1904,12 +2107,12 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1904
2107
|
};
|
|
1905
2108
|
const UserVideoListData = await GlobalGetData2(data2.methodType, {
|
|
1906
2109
|
...customConfig,
|
|
1907
|
-
url:
|
|
2110
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1908
2111
|
});
|
|
1909
2112
|
return UserVideoListData;
|
|
1910
2113
|
}
|
|
1911
2114
|
case "\u70ED\u70B9\u8BCD\u6570\u636E": {
|
|
1912
|
-
const url =
|
|
2115
|
+
const url = douyinApiUrls2.\u70ED\u70B9\u8BCD({ query: data2.query, number: data2.number ?? 10 });
|
|
1913
2116
|
const customConfig = {
|
|
1914
2117
|
...baseRequestConfig,
|
|
1915
2118
|
headers: {
|
|
@@ -1921,7 +2124,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1921
2124
|
};
|
|
1922
2125
|
const SuggestWordsData = await GlobalGetData2(data2.methodType, {
|
|
1923
2126
|
...customConfig,
|
|
1924
|
-
url:
|
|
2127
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1925
2128
|
});
|
|
1926
2129
|
return SuggestWordsData;
|
|
1927
2130
|
}
|
|
@@ -1941,14 +2144,14 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1941
2144
|
};
|
|
1942
2145
|
while (fetchedSearchList.length < Number(data2.number ?? 10)) {
|
|
1943
2146
|
const requestCount = Math.min(Number(data2.number ?? 50) - fetchedSearchList.length, maxPageSize);
|
|
1944
|
-
const url =
|
|
2147
|
+
const url = douyinApiUrls2.\u641C\u7D22({
|
|
1945
2148
|
query: data2.query,
|
|
1946
2149
|
number: requestCount,
|
|
1947
2150
|
search_id: search_id === "" ? void 0 : search_id
|
|
1948
2151
|
});
|
|
1949
2152
|
const response = await GlobalGetData2(data2.methodType, {
|
|
1950
2153
|
...customConfig,
|
|
1951
|
-
url:
|
|
2154
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1952
2155
|
});
|
|
1953
2156
|
if (((_b = response.data) == null ? void 0 : _b.length) === 0) {
|
|
1954
2157
|
logger.warn("\u83B7\u53D6\u641C\u7D22\u6570\u636E\u5931\u8D25\uFF01\u8BF7\u6C42\u6210\u529F\u4F46\u63A5\u53E3\u8FD4\u56DE\u5185\u5BB9\u4E3A\u7A7A\n\u4F60\u7684\u6296\u97F3ck\u53EF\u80FD\u5DF2\u7ECF\u5931\u6548\uFF01\n\u8BF7\u6C42\u7C7B\u578B\uFF1A" + data2.methodType);
|
|
@@ -1968,24 +2171,24 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
1968
2171
|
return finalResponse;
|
|
1969
2172
|
}
|
|
1970
2173
|
case "\u52A8\u6001\u8868\u60C5\u6570\u636E": {
|
|
1971
|
-
const url =
|
|
2174
|
+
const url = douyinApiUrls2.\u4E92\u52A8\u8868\u60C5();
|
|
1972
2175
|
const ExpressionPlusData = await GlobalGetData2(data2.methodType, {
|
|
1973
2176
|
...baseRequestConfig,
|
|
1974
|
-
url:
|
|
2177
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1975
2178
|
});
|
|
1976
2179
|
return ExpressionPlusData;
|
|
1977
2180
|
}
|
|
1978
2181
|
case "\u97F3\u4E50\u6570\u636E": {
|
|
1979
|
-
const url =
|
|
2182
|
+
const url = douyinApiUrls2.\u80CC\u666F\u97F3\u4E50({ music_id: data2.music_id });
|
|
1980
2183
|
const MusicData = await GlobalGetData2(data2.methodType, {
|
|
1981
2184
|
...baseRequestConfig,
|
|
1982
|
-
url:
|
|
2185
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
1983
2186
|
});
|
|
1984
2187
|
return MusicData;
|
|
1985
2188
|
}
|
|
1986
2189
|
case "\u76F4\u64AD\u95F4\u4FE1\u606F\u6570\u636E": {
|
|
1987
|
-
let url =
|
|
1988
|
-
const fetchUrl =
|
|
2190
|
+
let url = douyinApiUrls2.\u7528\u6237\u4E3B\u9875\u4FE1\u606F({ sec_uid: data2.sec_uid });
|
|
2191
|
+
const fetchUrl = buildSignedUrl(url, signType, userAgent);
|
|
1989
2192
|
const customConfig = {
|
|
1990
2193
|
...baseRequestConfig,
|
|
1991
2194
|
headers: {
|
|
@@ -2022,7 +2225,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2022
2225
|
};
|
|
2023
2226
|
}
|
|
2024
2227
|
const room_data = JSON.parse(UserInfoData.user.room_data);
|
|
2025
|
-
url =
|
|
2228
|
+
url = douyinApiUrls2.\u76F4\u64AD\u95F4\u4FE1\u606F({ room_id: UserInfoData.user.room_id_str, web_rid: room_data.owner.web_rid });
|
|
2026
2229
|
const liveCustomConfig = {
|
|
2027
2230
|
...baseRequestConfig,
|
|
2028
2231
|
headers: {
|
|
@@ -2034,15 +2237,15 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2034
2237
|
};
|
|
2035
2238
|
const LiveRoomData = await GlobalGetData2(data2.methodType, {
|
|
2036
2239
|
...liveCustomConfig,
|
|
2037
|
-
url:
|
|
2240
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
2038
2241
|
});
|
|
2039
2242
|
return LiveRoomData;
|
|
2040
2243
|
}
|
|
2041
2244
|
case "\u7533\u8BF7\u4E8C\u7EF4\u7801\u6570\u636E": {
|
|
2042
|
-
const url =
|
|
2245
|
+
const url = douyinApiUrls2.\u7533\u8BF7\u4E8C\u7EF4\u7801({ verify_fp: data2.verify_fp });
|
|
2043
2246
|
const LoginQrcodeStatusData = await GlobalGetData2(data2.methodType, {
|
|
2044
2247
|
...baseRequestConfig,
|
|
2045
|
-
url:
|
|
2248
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
2046
2249
|
});
|
|
2047
2250
|
return LoginQrcodeStatusData;
|
|
2048
2251
|
}
|
|
@@ -2052,7 +2255,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2052
2255
|
const endTime = data2.end_time ?? data2.duration;
|
|
2053
2256
|
const totalDuration = endTime - startTime;
|
|
2054
2257
|
if (totalDuration <= MAX_SEGMENT_DURATION) {
|
|
2055
|
-
const url =
|
|
2258
|
+
const url = douyinApiUrls2.\u5F39\u5E55({
|
|
2056
2259
|
aweme_id: data2.aweme_id,
|
|
2057
2260
|
start_time: startTime,
|
|
2058
2261
|
end_time: endTime,
|
|
@@ -2060,7 +2263,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2060
2263
|
});
|
|
2061
2264
|
const DanmakuData = await GlobalGetData2(data2.methodType, {
|
|
2062
2265
|
...baseRequestConfig,
|
|
2063
|
-
url:
|
|
2266
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
2064
2267
|
});
|
|
2065
2268
|
return DanmakuData;
|
|
2066
2269
|
}
|
|
@@ -2073,7 +2276,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2073
2276
|
}
|
|
2074
2277
|
logger.debug(`\u5F39\u5E55\u6570\u636E\u9700\u8981\u5206${segments.length}\u6BB5\u83B7\u53D6\uFF0C\u603B\u65F6\u957F\uFF1A${totalDuration}ms`);
|
|
2075
2278
|
const segmentPromises = segments.map(async (segment, index) => {
|
|
2076
|
-
const url =
|
|
2279
|
+
const url = douyinApiUrls2.\u5F39\u5E55({
|
|
2077
2280
|
aweme_id: data2.aweme_id,
|
|
2078
2281
|
start_time: segment.start,
|
|
2079
2282
|
end_time: segment.end,
|
|
@@ -2082,7 +2285,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2082
2285
|
try {
|
|
2083
2286
|
const segmentData = await GlobalGetData2(`${data2.methodType}-\u6BB5${index + 1}`, {
|
|
2084
2287
|
...baseRequestConfig,
|
|
2085
|
-
url:
|
|
2288
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
2086
2289
|
});
|
|
2087
2290
|
logger.debug(`\u5F39\u5E55\u7B2C${index + 1}\u6BB5\u83B7\u53D6\u6210\u529F (${segment.start}ms-${segment.end}ms)`);
|
|
2088
2291
|
return segmentData;
|
|
@@ -2130,7 +2333,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
|
|
|
2130
2333
|
}
|
|
2131
2334
|
}
|
|
2132
2335
|
};
|
|
2133
|
-
var fetchPaginatedData = async (type, apiUrlGenerator, params, maxPageSize, requestConfig) => {
|
|
2336
|
+
var fetchPaginatedData = async (type, apiUrlGenerator, params, maxPageSize, requestConfig, signType = "a_bogus") => {
|
|
2134
2337
|
var _a;
|
|
2135
2338
|
let cursor = params.cursor ?? 0;
|
|
2136
2339
|
let fetchedData = [];
|
|
@@ -2145,7 +2348,7 @@ var fetchPaginatedData = async (type, apiUrlGenerator, params, maxPageSize, requ
|
|
|
2145
2348
|
});
|
|
2146
2349
|
const response = await GlobalGetData2(type, {
|
|
2147
2350
|
...requestConfig,
|
|
2148
|
-
url:
|
|
2351
|
+
url: buildSignedUrl(url, signType, userAgent)
|
|
2149
2352
|
});
|
|
2150
2353
|
fetchedData.push(...response.comments || response.data || []);
|
|
2151
2354
|
tmpresp = response;
|
|
@@ -2436,7 +2639,7 @@ var DouyinDanmakuParamsSchema = z.object({
|
|
|
2436
2639
|
aweme_id: z.string({ error: "\u89C6\u9891ID\u5FC5\u987B\u662F\u5B57\u7B26\u4E32" }).min(1, { error: "\u89C6\u9891ID\u4E0D\u80FD\u4E3A\u7A7A" }),
|
|
2437
2640
|
start_time: z.coerce.number({ error: "\u5F00\u59CB\u65F6\u95F4\u5FC5\u987B\u662F\u6570\u5B57" }).int({ error: "\u5F00\u59CB\u65F6\u95F4\u5FC5\u987B\u662F\u6574\u6570" }).min(0, { error: "\u5F00\u59CB\u65F6\u95F4\u4E0D\u80FD\u5C0F\u4E8E0" }).optional(),
|
|
2438
2641
|
end_time: z.coerce.number({ error: "\u7ED3\u675F\u65F6\u95F4\u5FC5\u987B\u662F\u6570\u5B57" }).int({ error: "\u7ED3\u675F\u65F6\u95F4\u5FC5\u987B\u662F\u6574\u6570" }).min(0, { error: "\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u5C0F\u4E8E0" }).optional(),
|
|
2439
|
-
duration: z.number({ error: "\u89C6\u9891\u65F6\u957F\u5FC5\u987B\u662F\u6570\u5B57" }).int({ error: "\u89C6\u9891\u65F6\u957F\u5FC5\u987B\u662F\u6574\u6570" }).min(0, { error: "\u89C6\u9891\u65F6\u957F\u4E0D\u80FD\u5C0F\u4E8E0" })
|
|
2642
|
+
duration: z.coerce.number({ error: "\u89C6\u9891\u65F6\u957F\u5FC5\u987B\u662F\u6570\u5B57" }).int({ error: "\u89C6\u9891\u65F6\u957F\u5FC5\u987B\u662F\u6574\u6570" }).min(0, { error: "\u89C6\u9891\u65F6\u957F\u4E0D\u80FD\u5C0F\u4E8E0" })
|
|
2440
2643
|
}).refine(
|
|
2441
2644
|
(data2) => {
|
|
2442
2645
|
if (data2.end_time !== void 0) {
|
package/dist/default/index.d.ts
CHANGED
|
@@ -19850,6 +19850,12 @@ declare class douyinSign {
|
|
|
19850
19850
|
* @returns 对此地址签名后的URL查询参数
|
|
19851
19851
|
*/
|
|
19852
19852
|
static AB(url: string, userAgent?: string): string;
|
|
19853
|
+
/**
|
|
19854
|
+
* X-Bogus 签名算法
|
|
19855
|
+
* @param url 需要签名的地址
|
|
19856
|
+
* @returns 对此地址签名后的URL查询参数
|
|
19857
|
+
*/
|
|
19858
|
+
static XB(url: string, userAgent?: string): string;
|
|
19853
19859
|
/** 生成一个唯一的验证字符串 */
|
|
19854
19860
|
static VerifyFpManager(): string;
|
|
19855
19861
|
}
|