@iflyrpa/actions 2.0.0-beta.8 → 2.0.1
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/actions/getShipinhaoBgm/index.d.ts +1 -1
- package/dist/actions/shipinhaoPublish/index.d.ts +3 -8
- package/dist/actions/shipinhaoPublish/rpa-server.d.ts +2 -0
- package/dist/actions/shipinhaoPublish/rpa.d.ts +4 -0
- package/dist/actions/shipinhaoPublish/uploader.d.ts +102 -0
- package/dist/bundle.js +729 -222
- package/dist/bundle.js.map +1 -1
- package/dist/index.js +726 -221
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +726 -221
- package/dist/index.mjs.map +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1721,7 +1721,7 @@ var __webpack_modules__ = {
|
|
|
1721
1721
|
module.exports = GenXSCommon;
|
|
1722
1722
|
},
|
|
1723
1723
|
"./src/utils/douyin/csrfToken.js": function(module, __unused_webpack_exports, __webpack_require__) {
|
|
1724
|
-
const
|
|
1724
|
+
const crypto = __webpack_require__("crypto");
|
|
1725
1725
|
function generateCsrfToken(options = {}) {
|
|
1726
1726
|
const { cookies = [], url = '', method = 'POST' } = options;
|
|
1727
1727
|
const sessionid = getCookieValue(cookies, 'sessionid') || '';
|
|
@@ -1733,7 +1733,7 @@ var __webpack_modules__ = {
|
|
|
1733
1733
|
const timestampHex = timestamp.toString(16).padStart(8, '0');
|
|
1734
1734
|
const random = generateRandomHex(8);
|
|
1735
1735
|
const signData = `${method}${url}${sessionid}${uid_tt}${msToken}${ttwid}${timestamp}`;
|
|
1736
|
-
const hash =
|
|
1736
|
+
const hash = crypto.createHash('md5').update(signData).digest('hex');
|
|
1737
1737
|
const csrfToken = `0001${version}${timestampHex}${random}${hash}`;
|
|
1738
1738
|
return csrfToken;
|
|
1739
1739
|
}
|
|
@@ -1742,7 +1742,7 @@ var __webpack_modules__ = {
|
|
|
1742
1742
|
return cookie ? cookie.value : '';
|
|
1743
1743
|
}
|
|
1744
1744
|
function generateRandomHex(length) {
|
|
1745
|
-
const bytes =
|
|
1745
|
+
const bytes = crypto.randomBytes(Math.ceil(length / 2));
|
|
1746
1746
|
return bytes.toString('hex').slice(0, length);
|
|
1747
1747
|
}
|
|
1748
1748
|
function generateCsrfTokenAdvanced(options = {}) {
|
|
@@ -1775,8 +1775,8 @@ var __webpack_modules__ = {
|
|
|
1775
1775
|
userAgent
|
|
1776
1776
|
].filter(Boolean);
|
|
1777
1777
|
const signData = signParts.join('|');
|
|
1778
|
-
const firstHash =
|
|
1779
|
-
const secondHash =
|
|
1778
|
+
const firstHash = crypto.createHash('md5').update(signData).digest('hex');
|
|
1779
|
+
const secondHash = crypto.createHash('md5').update(firstHash + timestamp).digest('hex');
|
|
1780
1780
|
const timestampHex = timestampSec.toString(16).padStart(8, '0');
|
|
1781
1781
|
const random = generateRandomHex(16);
|
|
1782
1782
|
return `0001000${timestampHex.slice(0, 2)}${random}${secondHash}`;
|
|
@@ -1785,7 +1785,7 @@ var __webpack_modules__ = {
|
|
|
1785
1785
|
const sessionid = getCookieValue(cookies, 'sessionid') || 'default_session';
|
|
1786
1786
|
const timestamp = Math.floor(Date.now() / 1000);
|
|
1787
1787
|
const random = generateRandomHex(32);
|
|
1788
|
-
const hash =
|
|
1788
|
+
const hash = crypto.createHash('md5').update(`${sessionid}${timestamp}${random}`).digest('hex');
|
|
1789
1789
|
const timestampHex = timestamp.toString(16).padStart(8, '0');
|
|
1790
1790
|
return `0001000${timestampHex}${random}${hash}`.slice(0, 90);
|
|
1791
1791
|
}
|
|
@@ -2184,7 +2184,7 @@ var __webpack_modules__ = {
|
|
|
2184
2184
|
generateAuthorization: ()=>generateAuthorization,
|
|
2185
2185
|
randomS: ()=>randomS
|
|
2186
2186
|
});
|
|
2187
|
-
const
|
|
2187
|
+
const crypto = __webpack_require__("crypto");
|
|
2188
2188
|
const UNSIGNABLE_HEADERS = [
|
|
2189
2189
|
'authorization',
|
|
2190
2190
|
'content-type',
|
|
@@ -2195,10 +2195,10 @@ var __webpack_modules__ = {
|
|
|
2195
2195
|
'x-amzn-trace-id'
|
|
2196
2196
|
];
|
|
2197
2197
|
function sha256(data) {
|
|
2198
|
-
return
|
|
2198
|
+
return crypto.createHash('sha256').update(data, 'utf8').digest('hex');
|
|
2199
2199
|
}
|
|
2200
2200
|
function hmac(key, data) {
|
|
2201
|
-
return
|
|
2201
|
+
return crypto.createHmac('sha256', key).update(data, 'utf8').digest();
|
|
2202
2202
|
}
|
|
2203
2203
|
function getSigningKey(secretAccessKey, dateStamp, region, service) {
|
|
2204
2204
|
const kDate = hmac('AWS4' + secretAccessKey, dateStamp);
|
|
@@ -2287,7 +2287,7 @@ var __webpack_modules__ = {
|
|
|
2287
2287
|
canonicalRequestHash
|
|
2288
2288
|
].join('\n');
|
|
2289
2289
|
const signingKey = getSigningKey(secretAccessKey, dateStamp, region, service);
|
|
2290
|
-
const signature =
|
|
2290
|
+
const signature = crypto.createHmac('sha256', signingKey).update(stringToSign, 'utf8').digest('hex');
|
|
2291
2291
|
const authorization = `${algorithm} Credential=${accessKeyId}/${credentialScope}, SignedHeaders=${signedHeadersStr}, Signature=${signature}`;
|
|
2292
2292
|
return {
|
|
2293
2293
|
authorization,
|
|
@@ -2320,19 +2320,19 @@ var __webpack_modules__ = {
|
|
|
2320
2320
|
}
|
|
2321
2321
|
},
|
|
2322
2322
|
"./src/utils/douyin/reqSign.js.js": function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2323
|
-
const
|
|
2323
|
+
const crypto = __webpack_require__("crypto");
|
|
2324
2324
|
function bufferToHex(buffer) {
|
|
2325
2325
|
return buffer.toString('hex');
|
|
2326
2326
|
}
|
|
2327
2327
|
function generateReqSign(privateKeyPem, data) {
|
|
2328
2328
|
try {
|
|
2329
|
-
const privateKey =
|
|
2329
|
+
const privateKey = crypto.createPrivateKey({
|
|
2330
2330
|
key: privateKeyPem,
|
|
2331
2331
|
format: 'pem',
|
|
2332
2332
|
type: 'pkcs8'
|
|
2333
2333
|
});
|
|
2334
2334
|
const dataBuffer = Buffer.from(data, 'utf8');
|
|
2335
|
-
const signature =
|
|
2335
|
+
const signature = crypto.sign('sha256', dataBuffer, {
|
|
2336
2336
|
key: privateKey,
|
|
2337
2337
|
dsaEncoding: 'der'
|
|
2338
2338
|
});
|
|
@@ -5004,7 +5004,9 @@ var __webpack_exports__ = {};
|
|
|
5004
5004
|
});
|
|
5005
5005
|
const package_json_namespaceObject = require("@iflyrpa/share/package.json");
|
|
5006
5006
|
var package_json_default = /*#__PURE__*/ __webpack_require__.n(package_json_namespaceObject);
|
|
5007
|
-
var package_namespaceObject =
|
|
5007
|
+
var package_namespaceObject = {
|
|
5008
|
+
i8: "2.0.0"
|
|
5009
|
+
};
|
|
5008
5010
|
const share_namespaceObject = require("@iflyrpa/share");
|
|
5009
5011
|
const external_node_fs_namespaceObject = require("node:fs");
|
|
5010
5012
|
var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
|
|
@@ -9134,7 +9136,7 @@ var __webpack_exports__ = {};
|
|
|
9134
9136
|
message,
|
|
9135
9137
|
data: null
|
|
9136
9138
|
});
|
|
9137
|
-
const MockPublish =
|
|
9139
|
+
const MockPublish = false;
|
|
9138
9140
|
const rpa_server_scanRetryMaxCount = 60;
|
|
9139
9141
|
const rpa_server_waitQrcodeResultMaxTime = 2000 * rpa_server_scanRetryMaxCount;
|
|
9140
9142
|
const rpaServer = async (task, params)=>{
|
|
@@ -11198,8 +11200,7 @@ var __webpack_exports__ = {};
|
|
|
11198
11200
|
const http = new Http({
|
|
11199
11201
|
headers: {
|
|
11200
11202
|
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
11201
|
-
referer: "https://creator.douyin.com/"
|
|
11202
|
-
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
|
11203
|
+
referer: "https://creator.douyin.com/"
|
|
11203
11204
|
}
|
|
11204
11205
|
});
|
|
11205
11206
|
const res = await http.api({
|
|
@@ -11256,40 +11257,9 @@ var __webpack_exports__ = {};
|
|
|
11256
11257
|
const rid = ()=>`${Math.floor(Date.now() / 1e3).toString(16)}-${[
|
|
11257
11258
|
...Array(8)
|
|
11258
11259
|
].map(()=>Math.floor(16 * Math.random()).toString(16)).join("")}`;
|
|
11259
|
-
|
|
11260
|
-
const byteBuffer = new Uint8Array(16);
|
|
11261
|
-
const UUID_REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
|
|
11260
|
+
new Uint8Array(16);
|
|
11262
11261
|
const hexTable = [];
|
|
11263
11262
|
for(let i = 0; i < 256; i++)hexTable.push((i + 256).toString(16).substr(1));
|
|
11264
|
-
function initRandomGenerator() {
|
|
11265
|
-
if (randomValuesFunc) return randomValuesFunc;
|
|
11266
|
-
const globalCrypto = "undefined" != typeof crypto ? crypto : void 0;
|
|
11267
|
-
const globalMsCrypto = "undefined" != typeof msCrypto ? msCrypto : void 0;
|
|
11268
|
-
const cryptoAPI = globalCrypto?.getRandomValues?.bind(globalCrypto) || globalMsCrypto?.getRandomValues?.bind(globalMsCrypto);
|
|
11269
|
-
if (!cryptoAPI) throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
11270
|
-
randomValuesFunc = cryptoAPI;
|
|
11271
|
-
return randomValuesFunc;
|
|
11272
|
-
}
|
|
11273
|
-
function generateRandomBytes() {
|
|
11274
|
-
const rng = initRandomGenerator();
|
|
11275
|
-
return rng(byteBuffer);
|
|
11276
|
-
}
|
|
11277
|
-
function bytesToUuid(bytes, offset = 0) {
|
|
11278
|
-
const uuidString = (hexTable[bytes[offset + 0]] + hexTable[bytes[offset + 1]] + hexTable[bytes[offset + 2]] + hexTable[bytes[offset + 3]] + "-" + hexTable[bytes[offset + 4]] + hexTable[bytes[offset + 5]] + "-" + hexTable[bytes[offset + 6]] + hexTable[bytes[offset + 7]] + "-" + hexTable[bytes[offset + 8]] + hexTable[bytes[offset + 9]] + "-" + hexTable[bytes[offset + 10]] + hexTable[bytes[offset + 11]] + hexTable[bytes[offset + 12]] + hexTable[bytes[offset + 13]] + hexTable[bytes[offset + 14]] + hexTable[bytes[offset + 15]]).toLowerCase();
|
|
11279
|
-
if (!UUID_REGEX.test(uuidString)) throw new TypeError("Stringified UUID is invalid");
|
|
11280
|
-
return uuidString;
|
|
11281
|
-
}
|
|
11282
|
-
function utils_uuidv4(options = {}, buffer = null, bufferOffset = 0) {
|
|
11283
|
-
const rng = options.random || options.rng || generateRandomBytes;
|
|
11284
|
-
const bytes = rng();
|
|
11285
|
-
bytes[6] = 0x0f & bytes[6] | 0x40;
|
|
11286
|
-
bytes[8] = 0x3f & bytes[8] | 0x80;
|
|
11287
|
-
if (buffer) {
|
|
11288
|
-
for(let i = 0; i < 16; i++)buffer[bufferOffset + i] = bytes[i];
|
|
11289
|
-
return buffer;
|
|
11290
|
-
}
|
|
11291
|
-
return bytesToUuid(bytes);
|
|
11292
|
-
}
|
|
11293
11263
|
const createShipinhaoComment = async (_task, params)=>{
|
|
11294
11264
|
if (!params.content || "" === params.content.trim()) return (0, share_namespaceObject.response)(400, "评论内容不能为空", void 0);
|
|
11295
11265
|
if (!params.exportId) return (0, share_namespaceObject.response)(400, "exportId 不能为空", void 0);
|
|
@@ -12813,7 +12783,7 @@ var __webpack_exports__ = {};
|
|
|
12813
12783
|
const batch = imageUrls.slice(i, i + this.CONCURRENT_LIMIT);
|
|
12814
12784
|
const batchIndex = Math.floor(i / this.CONCURRENT_LIMIT) + 1;
|
|
12815
12785
|
const totalBatches = Math.ceil(total / this.CONCURRENT_LIMIT);
|
|
12816
|
-
console.log(`\n--- 批次 ${batchIndex}/${totalBatches} (${batch
|
|
12786
|
+
console.log(`\n--- 批次 ${batchIndex}/${totalBatches} (${batch?.length} 张) ---`);
|
|
12817
12787
|
const batchPromises = batch.map((url, idx)=>{
|
|
12818
12788
|
const globalIndex = i + idx;
|
|
12819
12789
|
return this.processSingleImage(url, globalIndex, total);
|
|
@@ -12858,11 +12828,15 @@ var __webpack_exports__ = {};
|
|
|
12858
12828
|
const { generateCsrfTokenAdvanced: mock_generateCsrfTokenAdvanced } = __webpack_require__("./src/utils/douyin/csrfToken.js");
|
|
12859
12829
|
const mock_mockAction = async (task, params)=>{
|
|
12860
12830
|
if (!params.extraParam || !params.extraParam["security-sdk/s_sdk_pri_key"] || !params.extraParam["security-sdk/s_sdk_pub_key"] || !params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"]) return (0, share_namespaceObject.response)(400, "extraParam 参数缺失或不完整", "");
|
|
12831
|
+
const userAgent = params.userAgent || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36";
|
|
12861
12832
|
const tmpCachePath = task.getTmpPath();
|
|
12862
12833
|
let bdTicketGuardClientDataV2 = params.cookies.find((e)=>"bd_ticket_guard_client_data" === e.name)?.value || "";
|
|
12863
12834
|
if (!bdTicketGuardClientDataV2) return (0, share_namespaceObject.response)(400, "bdTicketGuardClientDataV2 不能为空", "");
|
|
12864
12835
|
bdTicketGuardClientDataV2 = decodeURIComponent(bdTicketGuardClientDataV2);
|
|
12865
12836
|
console.log("原始 bdTicketGuardClientDataV2:", bdTicketGuardClientDataV2);
|
|
12837
|
+
task.logger.warn("原始 bdTicketGuardClientDataV2", {
|
|
12838
|
+
bdTicketGuardClientDataV2
|
|
12839
|
+
});
|
|
12866
12840
|
try {
|
|
12867
12841
|
bdTicketGuardClientDataV2 = atob(bdTicketGuardClientDataV2);
|
|
12868
12842
|
console.log("解码后 bdTicketGuardClientDataV2:", bdTicketGuardClientDataV2);
|
|
@@ -12870,6 +12844,9 @@ var __webpack_exports__ = {};
|
|
|
12870
12844
|
console.error("bdTicketGuardClientDataV2 解码失败:", error);
|
|
12871
12845
|
return (0, share_namespaceObject.response)(500, "bdTicketGuardClientDataV2 解码失败", "");
|
|
12872
12846
|
}
|
|
12847
|
+
task.logger.warn("解码后 bdTicketGuardClientDataV2:", {
|
|
12848
|
+
bdTicketGuardClientDataV2
|
|
12849
|
+
});
|
|
12873
12850
|
let ree_public_key = "";
|
|
12874
12851
|
let ts_sign = "";
|
|
12875
12852
|
try {
|
|
@@ -12881,16 +12858,23 @@ var __webpack_exports__ = {};
|
|
|
12881
12858
|
const publicKey = JSON.parse(params.extraParam["security-sdk/s_sdk_pub_key"] || "{}").data;
|
|
12882
12859
|
const signData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
|
|
12883
12860
|
console.log("privateKey:", privateKey);
|
|
12861
|
+
task.logger.warn("privateKey", {
|
|
12862
|
+
privateKey
|
|
12863
|
+
});
|
|
12884
12864
|
console.log("publicKey:", publicKey);
|
|
12885
|
-
|
|
12865
|
+
task.logger.warn("signData", {
|
|
12866
|
+
signData
|
|
12867
|
+
});
|
|
12886
12868
|
let bdTicketGuardClientData = {
|
|
12887
12869
|
ts_sign,
|
|
12888
12870
|
req_content: "ticket,path,timestamp",
|
|
12889
12871
|
timestamp: Math.floor(Date.now() / 1000),
|
|
12890
12872
|
req_sign: generateReqSignFromTicket(signData.ticket, privateKey)
|
|
12891
12873
|
};
|
|
12892
|
-
console.log("bdTicketGuardClientData:", bdTicketGuardClientData);
|
|
12893
12874
|
bdTicketGuardClientData = btoa(JSON.stringify(bdTicketGuardClientData));
|
|
12875
|
+
task.logger.warn("bdTicketGuardClientData", {
|
|
12876
|
+
bdTicketGuardClientData
|
|
12877
|
+
});
|
|
12894
12878
|
const sessionidCookie = params.cookies.find((it)=>"msToken" === it.name)?.value;
|
|
12895
12879
|
if (!sessionidCookie) return {
|
|
12896
12880
|
code: 414,
|
|
@@ -12901,7 +12885,7 @@ var __webpack_exports__ = {};
|
|
|
12901
12885
|
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
12902
12886
|
origin: "https://creator.douyin.com",
|
|
12903
12887
|
referer: "https://creator.douyin.com/",
|
|
12904
|
-
"user-agent":
|
|
12888
|
+
"user-agent": userAgent
|
|
12905
12889
|
};
|
|
12906
12890
|
const publishParams = {
|
|
12907
12891
|
read_aid: "2906",
|
|
@@ -12912,13 +12896,16 @@ var __webpack_exports__ = {};
|
|
|
12912
12896
|
browser_language: "zh-CN",
|
|
12913
12897
|
browser_platform: "Win32",
|
|
12914
12898
|
browser_name: "Mozilla",
|
|
12915
|
-
browser_version:
|
|
12899
|
+
browser_version: userAgent,
|
|
12916
12900
|
browser_online: "true",
|
|
12917
12901
|
timezone_name: "Asia/Shanghai",
|
|
12918
12902
|
support_h265: "1",
|
|
12919
12903
|
msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
|
|
12920
12904
|
a_bogus: ""
|
|
12921
12905
|
};
|
|
12906
|
+
task.logger.warn("publishParams", {
|
|
12907
|
+
publishParams
|
|
12908
|
+
});
|
|
12922
12909
|
const publishData = {
|
|
12923
12910
|
item: {
|
|
12924
12911
|
common: {
|
|
@@ -12948,7 +12935,10 @@ var __webpack_exports__ = {};
|
|
|
12948
12935
|
}
|
|
12949
12936
|
}
|
|
12950
12937
|
};
|
|
12951
|
-
const aBogus = mock_sign_reply(publishParams,
|
|
12938
|
+
const aBogus = mock_sign_reply(publishParams, userAgent);
|
|
12939
|
+
task.logger.warn("aBogusaBogusaBogus", {
|
|
12940
|
+
aBogus
|
|
12941
|
+
});
|
|
12952
12942
|
publishParams.a_bogus = aBogus;
|
|
12953
12943
|
const queryString = new URLSearchParams(publishParams).toString();
|
|
12954
12944
|
const args = [
|
|
@@ -12964,6 +12954,9 @@ var __webpack_exports__ = {};
|
|
|
12964
12954
|
headers
|
|
12965
12955
|
});
|
|
12966
12956
|
const proxyHttp = new Http(...args);
|
|
12957
|
+
task.logger.warn("queryString", {
|
|
12958
|
+
queryString
|
|
12959
|
+
});
|
|
12967
12960
|
const uploader = new DouyinImageUploader(proxyHttp, headers, queryString, tmpCachePath);
|
|
12968
12961
|
if (params.coverImage) {
|
|
12969
12962
|
const coverUri = await uploader.uploadCover(params.coverImage);
|
|
@@ -12981,6 +12974,9 @@ var __webpack_exports__ = {};
|
|
|
12981
12974
|
}
|
|
12982
12975
|
proxyHttp.addResponseInterceptor((response)=>{
|
|
12983
12976
|
console.log("拦截器收到响应:", JSON.stringify(response.data));
|
|
12977
|
+
task.logger.warn("拦截器收到响应", {
|
|
12978
|
+
data: JSON.stringify(response.data)
|
|
12979
|
+
});
|
|
12984
12980
|
if (!response || !response.data) return;
|
|
12985
12981
|
const responseData = response.data;
|
|
12986
12982
|
if (response && responseData?.status_code && 0 !== responseData.status_code) return {
|
|
@@ -12994,7 +12990,7 @@ var __webpack_exports__ = {};
|
|
|
12994
12990
|
const publishQuery = {
|
|
12995
12991
|
...publishParams
|
|
12996
12992
|
};
|
|
12997
|
-
publishQuery.a_bogus = mock_sign_reply(publishQuery,
|
|
12993
|
+
publishQuery.a_bogus = mock_sign_reply(publishQuery, userAgent);
|
|
12998
12994
|
const publishQueryParams = new URLSearchParams(publishQuery).toString();
|
|
12999
12995
|
function generateRandomString(length) {
|
|
13000
12996
|
const characters = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
@@ -13010,9 +13006,12 @@ var __webpack_exports__ = {};
|
|
|
13010
13006
|
cookies: params.cookies,
|
|
13011
13007
|
url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
|
|
13012
13008
|
method: "POST",
|
|
13013
|
-
userAgent
|
|
13009
|
+
userAgent
|
|
13014
13010
|
});
|
|
13015
13011
|
console.log("发布数据", JSON.stringify(publishData));
|
|
13012
|
+
task.logger.warn("发布数据", {
|
|
13013
|
+
data: JSON.stringify(publishData)
|
|
13014
|
+
});
|
|
13016
13015
|
const publishResult = await proxyHttp.api({
|
|
13017
13016
|
method: "post",
|
|
13018
13017
|
url: `https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`,
|
|
@@ -13028,15 +13027,16 @@ var __webpack_exports__ = {};
|
|
|
13028
13027
|
"Bd-ticket-guard-version": "2",
|
|
13029
13028
|
"Bd-ticket-guard-web-sign-type": "1",
|
|
13030
13029
|
"Bd-ticket-guard-web-version": "2",
|
|
13031
|
-
"X-secsdk-csrf-token": csrfToken
|
|
13032
|
-
"X-tt-session-dtrait": params.cookies.find((e)=>"x-tt-session-dtrait" === e.name)?.value || ""
|
|
13030
|
+
"X-secsdk-csrf-token": csrfToken
|
|
13033
13031
|
}
|
|
13034
13032
|
}, {
|
|
13035
13033
|
retries: 2,
|
|
13036
13034
|
retryDelay: 500,
|
|
13037
13035
|
timeout: 12000
|
|
13038
13036
|
});
|
|
13039
|
-
console.log("publishResult", publishResult);
|
|
13037
|
+
console.log("publishResult", JSON.stringify(publishResult));
|
|
13038
|
+
task.logger.warn("发布数据");
|
|
13039
|
+
task.logger.warn(JSON.stringify(publishData));
|
|
13040
13040
|
const isSuccess = 0 === publishResult.status_code;
|
|
13041
13041
|
const message = `图文发布${isSuccess ? "成功" : `失败,原因:${publishResult.status_msg}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
13042
13042
|
const data = isSuccess ? publishResult.item_id || "" : "";
|
|
@@ -13135,7 +13135,7 @@ var __webpack_exports__ = {};
|
|
|
13135
13135
|
timeout: 20000
|
|
13136
13136
|
});
|
|
13137
13137
|
task.logger.info("✓ 登录状态正常");
|
|
13138
|
-
} catch (
|
|
13138
|
+
} catch (_error) {
|
|
13139
13139
|
task.logger.error("✗ 登录失效或页面加载异常");
|
|
13140
13140
|
return {
|
|
13141
13141
|
code: 414,
|
|
@@ -13207,11 +13207,11 @@ var __webpack_exports__ = {};
|
|
|
13207
13207
|
task.logger.warn(`添加话题标签失败: ${error}`);
|
|
13208
13208
|
}
|
|
13209
13209
|
}
|
|
13210
|
-
if (params.mix
|
|
13210
|
+
if (params.mix?.mix_name) {
|
|
13211
13211
|
task.logger.info(`选择合集: ${params.mix.mix_name}`);
|
|
13212
13212
|
const instanceCollection = page.locator("[class^='mix-sel-wrap'] .semi-select").nth(1);
|
|
13213
13213
|
await instanceCollection.click();
|
|
13214
|
-
await page.waitForTimeout(
|
|
13214
|
+
await page.waitForTimeout(2000);
|
|
13215
13215
|
page.locator(".semi-select-option-list .semi-select-option").filter({
|
|
13216
13216
|
hasText: params.mix.mix_name
|
|
13217
13217
|
}).first().click({
|
|
@@ -13254,7 +13254,7 @@ var __webpack_exports__ = {};
|
|
|
13254
13254
|
task.logger.info("找到匹配的音乐,准备选择");
|
|
13255
13255
|
await matchedCard.hover();
|
|
13256
13256
|
task.logger.info("已 hover 到音乐卡片");
|
|
13257
|
-
await page.waitForTimeout(
|
|
13257
|
+
await page.waitForTimeout(2000);
|
|
13258
13258
|
const selectButton = matchedCard.locator(".semi-button").first();
|
|
13259
13259
|
const buttonClicked = await safeClick(selectButton);
|
|
13260
13260
|
if (!buttonClicked) throw new Error("点击音乐选择按钮失败");
|
|
@@ -13343,8 +13343,10 @@ var __webpack_exports__ = {};
|
|
|
13343
13343
|
console.log("监听响应事件");
|
|
13344
13344
|
page.on("response", handleResponse);
|
|
13345
13345
|
console.log("点击发布按钮");
|
|
13346
|
-
|
|
13347
|
-
|
|
13346
|
+
setTimeout(()=>{
|
|
13347
|
+
page.locator("#DCPF button:has-text('发布')").first().click();
|
|
13348
|
+
console.log("发布按钮已点击");
|
|
13349
|
+
}, 1000);
|
|
13348
13350
|
});
|
|
13349
13351
|
console.log("发布成功了");
|
|
13350
13352
|
await page.close();
|
|
@@ -16148,33 +16150,257 @@ var __webpack_exports__ = {};
|
|
|
16148
16150
|
if ("server" === params.actionType) return shipinhaoLogin_rpa_server_rpaServer(task, params);
|
|
16149
16151
|
return executeAction(shipinhaoLogin_rpa_server_rpaServer)(task, params);
|
|
16150
16152
|
};
|
|
16151
|
-
|
|
16152
|
-
|
|
16153
|
-
|
|
16154
|
-
|
|
16155
|
-
|
|
16156
|
-
|
|
16157
|
-
|
|
16158
|
-
|
|
16159
|
-
|
|
16160
|
-
|
|
16161
|
-
|
|
16162
|
-
|
|
16163
|
-
|
|
16164
|
-
|
|
16165
|
-
|
|
16166
|
-
|
|
16153
|
+
class VideoChannelUploader {
|
|
16154
|
+
constructor(config = {}){
|
|
16155
|
+
this.uploadTaskId = "";
|
|
16156
|
+
this.partInfo = [];
|
|
16157
|
+
this.md5 = "";
|
|
16158
|
+
this.chunkCount = 0;
|
|
16159
|
+
this.uploadedChunks = 0;
|
|
16160
|
+
this.startTime = 0;
|
|
16161
|
+
this.uploadSpeed = 0;
|
|
16162
|
+
this.speedRecords = [];
|
|
16163
|
+
this.chunkSize = config.chunkSize || 8388608;
|
|
16164
|
+
this.concurrentLimit = config.concurrentLimit || 4;
|
|
16165
|
+
this.singleFileSize = config.singleFileSize || 10485760;
|
|
16166
|
+
}
|
|
16167
|
+
calculateMd5(buffer) {
|
|
16168
|
+
const MAX_SIZE = 5242880;
|
|
16169
|
+
const slice = buffer.length > MAX_SIZE ? buffer.slice(0, MAX_SIZE) : buffer;
|
|
16170
|
+
return external_node_crypto_default().createHash("md5").update(slice).digest("hex");
|
|
16171
|
+
}
|
|
16172
|
+
calculateChunkMd5(buffer) {
|
|
16173
|
+
return external_node_crypto_default().createHash("md5").update(buffer).digest("hex");
|
|
16174
|
+
}
|
|
16175
|
+
generateUUID() {
|
|
16176
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c)=>{
|
|
16177
|
+
const r = 16 * Math.random() | 0;
|
|
16178
|
+
const v = "x" === c ? r : 0x3 & r | 0x8;
|
|
16179
|
+
return v.toString(16);
|
|
16180
|
+
});
|
|
16181
|
+
}
|
|
16182
|
+
getImageSize(buffer) {
|
|
16183
|
+
try {
|
|
16184
|
+
if (0x89 === buffer[0] && 0x50 === buffer[1]) return {
|
|
16185
|
+
width: buffer.readUInt32BE(16),
|
|
16186
|
+
height: buffer.readUInt32BE(20)
|
|
16187
|
+
};
|
|
16188
|
+
if (0xff === buffer[0] && 0xd8 === buffer[1]) {
|
|
16189
|
+
let offset = 2;
|
|
16190
|
+
while(offset < buffer.length){
|
|
16191
|
+
if (0xff !== buffer[offset]) break;
|
|
16192
|
+
const marker = buffer[offset + 1];
|
|
16193
|
+
const size = buffer.readUInt16BE(offset + 2);
|
|
16194
|
+
if (0xc0 === marker || 0xc1 === marker || 0xc2 === marker) return {
|
|
16195
|
+
height: buffer.readUInt16BE(offset + 5),
|
|
16196
|
+
width: buffer.readUInt16BE(offset + 7)
|
|
16197
|
+
};
|
|
16198
|
+
offset += size + 2;
|
|
16199
|
+
}
|
|
16200
|
+
}
|
|
16201
|
+
if (0x47 === buffer[0] && 0x49 === buffer[1]) return {
|
|
16202
|
+
width: buffer.readUInt16LE(6),
|
|
16203
|
+
height: buffer.readUInt16LE(8)
|
|
16204
|
+
};
|
|
16205
|
+
return {
|
|
16206
|
+
width: 0,
|
|
16207
|
+
height: 0
|
|
16208
|
+
};
|
|
16209
|
+
} catch {
|
|
16210
|
+
return {
|
|
16211
|
+
width: 0,
|
|
16212
|
+
height: 0
|
|
16213
|
+
};
|
|
16214
|
+
}
|
|
16215
|
+
}
|
|
16216
|
+
async readFile(filePath) {
|
|
16217
|
+
if (filePath.startsWith("http://") || filePath.startsWith("https://")) {
|
|
16218
|
+
const resp = await external_axios_default().get(filePath, {
|
|
16167
16219
|
responseType: "arraybuffer"
|
|
16168
16220
|
});
|
|
16169
|
-
return Buffer.from(
|
|
16221
|
+
return Buffer.from(resp.data);
|
|
16170
16222
|
}
|
|
16171
|
-
|
|
16172
|
-
|
|
16173
|
-
|
|
16174
|
-
|
|
16175
|
-
|
|
16223
|
+
return external_node_fs_default().promises.readFile(filePath);
|
|
16224
|
+
}
|
|
16225
|
+
async getUploadId(fileSize, fileName, uin, authKey, taskId) {
|
|
16226
|
+
const blockSum = Math.ceil(fileSize / this.chunkSize);
|
|
16227
|
+
const blockPartLength = [];
|
|
16228
|
+
for(let i = 1; i <= blockSum; i++){
|
|
16229
|
+
const end = Math.min(i * this.chunkSize, fileSize);
|
|
16230
|
+
blockPartLength.push(end);
|
|
16231
|
+
}
|
|
16232
|
+
const requestBody = {
|
|
16233
|
+
BlockSum: blockSum,
|
|
16234
|
+
BlockPartLength: blockPartLength
|
|
16235
|
+
};
|
|
16236
|
+
const headers = {
|
|
16237
|
+
"X-Arguments": `apptype=251&filetype=20304&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=2`,
|
|
16238
|
+
Authorization: authKey,
|
|
16239
|
+
Accept: "application/json, text/plain, */*",
|
|
16240
|
+
"Content-MD5": "null",
|
|
16241
|
+
Referer: "https://channels.weixin.qq.com/",
|
|
16242
|
+
Origin: "https://channels.weixin.qq.com/"
|
|
16243
|
+
};
|
|
16244
|
+
const resp = await external_axios_default().put("https://finderassistancea.video.qq.com/applyuploaddfs", requestBody, {
|
|
16245
|
+
headers
|
|
16246
|
+
});
|
|
16247
|
+
if (!resp.data?.UploadID) throw new Error(`获取 UploadID 失败: ${resp.data?.errMsg || "未知错误"}`);
|
|
16248
|
+
return resp.data.UploadID;
|
|
16249
|
+
}
|
|
16250
|
+
async uploadChunk(chunk, fileName, fileSize, uin, authKey, uploadId, partNumber, taskId, onProgress) {
|
|
16251
|
+
const md5Hash = this.calculateChunkMd5(chunk);
|
|
16252
|
+
const headers = {
|
|
16253
|
+
"Content-MD5": md5Hash,
|
|
16254
|
+
"X-Arguments": `apptype=251&filetype=20304&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=0`,
|
|
16255
|
+
Authorization: authKey,
|
|
16256
|
+
"Content-Type": "application/octet-stream",
|
|
16257
|
+
Referer: "https://channels.weixin.qq.com/platform/post/create",
|
|
16258
|
+
Origin: "https://channels.weixin.qq.com"
|
|
16259
|
+
};
|
|
16260
|
+
const url = `https://finderassistancea.video.qq.com/uploadpartdfs?PartNumber=${partNumber}&UploadID=${encodeURIComponent(uploadId)}`;
|
|
16261
|
+
const resp = await external_axios_default().put(url, chunk, {
|
|
16262
|
+
headers,
|
|
16263
|
+
maxBodyLength: 1 / 0,
|
|
16264
|
+
maxContentLength: 1 / 0,
|
|
16265
|
+
onUploadProgress: (progressEvent)=>{
|
|
16266
|
+
if (onProgress && progressEvent.bytes) onProgress(progressEvent.bytes);
|
|
16267
|
+
}
|
|
16268
|
+
});
|
|
16269
|
+
if (resp.data?.errCode !== void 0 && 0 !== resp.data.errCode) throw new Error(`分片 ${partNumber} 上传失败: ${resp.data.errMsg}`);
|
|
16270
|
+
return resp.data.ETag;
|
|
16271
|
+
}
|
|
16272
|
+
async confirmChunks(uploadId, fileName, uin, authKey, transFlag, taskId) {
|
|
16273
|
+
const headers = {
|
|
16274
|
+
"Content-MD5": "null",
|
|
16275
|
+
"X-Arguments": `apptype=251&filetype=20304&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=0&taskid=${taskId}&scene=0`,
|
|
16276
|
+
Authorization: authKey,
|
|
16277
|
+
Referer: "https://channels.weixin.qq.com/platform/post/create",
|
|
16278
|
+
Origin: "https://channels.weixin.qq.com"
|
|
16279
|
+
};
|
|
16280
|
+
const requestBody = {
|
|
16281
|
+
TransFlag: transFlag || "0_0",
|
|
16282
|
+
PartNumberMarker: "1"
|
|
16283
|
+
};
|
|
16284
|
+
const url = `https://finderassistancea.video.qq.com/listparts?UploadID=${encodeURIComponent(uploadId)}`;
|
|
16285
|
+
const resp = await external_axios_default().post(url, requestBody, {
|
|
16286
|
+
headers
|
|
16287
|
+
});
|
|
16288
|
+
if (resp.data?.ListPartsResult?.Part) return resp.data.ListPartsResult.Part.map((p)=>({
|
|
16289
|
+
PartNumber: parseInt(p.PartNumber),
|
|
16290
|
+
ETag: p.ETag
|
|
16291
|
+
}));
|
|
16292
|
+
return [];
|
|
16293
|
+
}
|
|
16294
|
+
async completeUpload(uploadId, fileName, fileSize, uin, authKey, transFlag, partInfo, taskId) {
|
|
16295
|
+
const headers = {
|
|
16296
|
+
"Content-MD5": "null",
|
|
16297
|
+
"X-Arguments": `apptype=251&filetype=20304&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=0`,
|
|
16298
|
+
Authorization: authKey,
|
|
16299
|
+
Referer: "https://channels.weixin.qq.com/platform/post/create",
|
|
16300
|
+
Origin: "https://channels.weixin.qq.com"
|
|
16301
|
+
};
|
|
16302
|
+
const requestBody = {
|
|
16303
|
+
TransFlag: transFlag || "0_0",
|
|
16304
|
+
PartInfo: partInfo
|
|
16305
|
+
};
|
|
16306
|
+
const url = `https://finderassistancea.video.qq.com/completepartuploaddfs?UploadID=${encodeURIComponent(uploadId)}`;
|
|
16307
|
+
const resp = await external_axios_default().post(url, requestBody, {
|
|
16308
|
+
headers
|
|
16309
|
+
});
|
|
16310
|
+
if (!resp.data?.DownloadURL) throw new Error(`完成上传失败: ${resp.data?.errMsg || "未知错误"}`);
|
|
16311
|
+
return resp.data.DownloadURL;
|
|
16312
|
+
}
|
|
16313
|
+
async asyncPool(concurrency, items, fn) {
|
|
16314
|
+
const executing = [];
|
|
16315
|
+
for (const item of items){
|
|
16316
|
+
const p = Promise.resolve().then(()=>fn(item));
|
|
16317
|
+
executing.push(p);
|
|
16318
|
+
if (executing.length >= concurrency) await Promise.race(executing);
|
|
16319
|
+
}
|
|
16320
|
+
await Promise.all(executing);
|
|
16321
|
+
}
|
|
16322
|
+
async upload(imagePath, uin, authKey, options = {}) {
|
|
16323
|
+
const { onProgress, transFlag } = options;
|
|
16324
|
+
const fileBuffer = await this.readFile(imagePath);
|
|
16325
|
+
const fileSize = fileBuffer.length;
|
|
16326
|
+
const fileName = external_node_path_default().basename(imagePath);
|
|
16327
|
+
if (fileSize > 20971520) throw new Error("图片大小超过 20MB 限制");
|
|
16328
|
+
this.md5 = this.calculateMd5(fileBuffer);
|
|
16329
|
+
const { width, height } = this.getImageSize(fileBuffer);
|
|
16330
|
+
this.startTime = Date.now();
|
|
16331
|
+
this.chunkCount = Math.ceil(fileSize / this.chunkSize);
|
|
16332
|
+
this.uploadedChunks = 0;
|
|
16333
|
+
this.partInfo = new Array(this.chunkCount).fill(null);
|
|
16334
|
+
const taskId = this.generateUUID();
|
|
16335
|
+
this.generateUUID();
|
|
16336
|
+
console.log(`[上传开始] 文件: ${fileName}, 大小: ${fileSize}, 分片: ${this.chunkCount}`);
|
|
16337
|
+
this.uploadTaskId = await this.getUploadId(fileSize, fileName, uin, authKey, taskId);
|
|
16338
|
+
console.log(`[获取 UploadID] ${this.uploadTaskId}`);
|
|
16339
|
+
this.startSpeedWatch();
|
|
16340
|
+
if (fileSize <= this.chunkSize) {
|
|
16341
|
+
console.log("[直接上传] 单文件模式");
|
|
16342
|
+
const etag = await this.uploadChunk(fileBuffer, fileName, fileSize, uin, authKey, this.uploadTaskId, 1, taskId, (delta)=>this.updateProgress(delta, onProgress));
|
|
16343
|
+
this.partInfo[0] = {
|
|
16344
|
+
PartNumber: 1,
|
|
16345
|
+
ETag: etag
|
|
16346
|
+
};
|
|
16347
|
+
this.uploadedChunks = 1;
|
|
16348
|
+
} else {
|
|
16349
|
+
console.log(`[分片上传] 并发数: ${this.concurrentLimit}`);
|
|
16350
|
+
const chunks = Array.from({
|
|
16351
|
+
length: this.chunkCount
|
|
16352
|
+
}, (_, i)=>i);
|
|
16353
|
+
await this.asyncPool(this.concurrentLimit, chunks, async (index)=>{
|
|
16354
|
+
const start = index * this.chunkSize;
|
|
16355
|
+
const end = Math.min((index + 1) * this.chunkSize, fileSize);
|
|
16356
|
+
const chunk = fileBuffer.slice(start, end);
|
|
16357
|
+
console.log(`[上传分片 ${index + 1}/${this.chunkCount}] 大小: ${chunk.length}`);
|
|
16358
|
+
const etag = await this.uploadChunk(chunk, fileName, fileSize, uin, authKey, this.uploadTaskId, index + 1, taskId, (delta)=>this.updateProgress(delta, onProgress));
|
|
16359
|
+
this.partInfo[index] = {
|
|
16360
|
+
PartNumber: index + 1,
|
|
16361
|
+
ETag: etag
|
|
16362
|
+
};
|
|
16363
|
+
this.uploadedChunks++;
|
|
16364
|
+
onProgress?.({
|
|
16365
|
+
uploadedChunks: this.uploadedChunks,
|
|
16366
|
+
totalChunks: this.chunkCount,
|
|
16367
|
+
percent: Math.floor(this.uploadedChunks / this.chunkCount * 100),
|
|
16368
|
+
speed: this.uploadSpeed
|
|
16369
|
+
});
|
|
16370
|
+
});
|
|
16371
|
+
}
|
|
16372
|
+
console.log("[完成上传] 合并分片...");
|
|
16373
|
+
const downloadUrl = await this.completeUpload(this.uploadTaskId, fileName, fileSize, uin, authKey, transFlag || "0_0", this.partInfo.filter(Boolean), taskId);
|
|
16374
|
+
this.stopSpeedWatch();
|
|
16375
|
+
return {
|
|
16376
|
+
downloadUrl,
|
|
16377
|
+
width,
|
|
16378
|
+
height,
|
|
16379
|
+
fileSize,
|
|
16380
|
+
md5: external_node_crypto_default().createHash("md5").update(fileBuffer).digest("hex")
|
|
16381
|
+
};
|
|
16382
|
+
}
|
|
16383
|
+
updateProgress(delta, onProgress) {}
|
|
16384
|
+
startSpeedWatch() {
|
|
16385
|
+
let lastUploaded = 0;
|
|
16386
|
+
this.speedInterval = setInterval(()=>{
|
|
16387
|
+
const current = this.uploadedChunks * this.chunkSize;
|
|
16388
|
+
this.uploadSpeed = Math.floor((current - lastUploaded) / 1024);
|
|
16389
|
+
this.speedRecords.push(this.uploadSpeed);
|
|
16390
|
+
lastUploaded = current;
|
|
16391
|
+
}, 1000);
|
|
16392
|
+
}
|
|
16393
|
+
stopSpeedWatch() {
|
|
16394
|
+
if (this.speedInterval) clearInterval(this.speedInterval);
|
|
16176
16395
|
}
|
|
16177
16396
|
}
|
|
16397
|
+
function generateUUID() {
|
|
16398
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c)=>{
|
|
16399
|
+
const r = 16 * Math.random() | 0;
|
|
16400
|
+
const v = "x" === c ? r : 0x3 & r | 0x8;
|
|
16401
|
+
return v.toString(16);
|
|
16402
|
+
});
|
|
16403
|
+
}
|
|
16178
16404
|
function mock_getTimeStamp(length) {
|
|
16179
16405
|
return Date.now().toString().substring(0, length);
|
|
16180
16406
|
}
|
|
@@ -16223,119 +16449,21 @@ var __webpack_exports__ = {};
|
|
|
16223
16449
|
});
|
|
16224
16450
|
return response.data;
|
|
16225
16451
|
}
|
|
16226
|
-
async function
|
|
16227
|
-
const
|
|
16228
|
-
|
|
16229
|
-
|
|
16230
|
-
if (fileSize < blockSize) blockPartLength.push(fileSize);
|
|
16231
|
-
else for(let i = 1; i <= blockSum; i++)if (i * blockSize <= fileSize) blockPartLength.push(i * blockSize);
|
|
16232
|
-
else {
|
|
16233
|
-
blockPartLength.push(fileSize);
|
|
16234
|
-
break;
|
|
16235
|
-
}
|
|
16236
|
-
const requestBody = {
|
|
16237
|
-
BlockSum: blockSum,
|
|
16238
|
-
BlockPartLength: blockPartLength
|
|
16239
|
-
};
|
|
16240
|
-
console.log("taskId:", taskId);
|
|
16241
|
-
const headers = {
|
|
16242
|
-
"X-Arguments": `apptype=251&filetype=${mediaType}&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=2`,
|
|
16243
|
-
Authorization: authKey,
|
|
16244
|
-
Accept: "application/json, text/plain, */*",
|
|
16245
|
-
"Content-MD5": "null",
|
|
16246
|
-
Referer: "https://channels.weixin.qq.com/",
|
|
16247
|
-
Origin: "https://channels.weixin.qq.com/"
|
|
16248
|
-
};
|
|
16249
|
-
try {
|
|
16250
|
-
const response = await external_axios_default().put("https://finderassistancea.video.qq.com/applyuploaddfs", requestBody, {
|
|
16251
|
-
headers
|
|
16252
|
-
});
|
|
16253
|
-
return response.data;
|
|
16254
|
-
} catch (e) {
|
|
16255
|
-
console.log("getUploadId error:", e);
|
|
16256
|
-
return {
|
|
16257
|
-
errCode: -1,
|
|
16258
|
-
errMsg: e instanceof Error ? e.message : "未知错误"
|
|
16259
|
-
};
|
|
16260
|
-
}
|
|
16261
|
-
}
|
|
16262
|
-
async function uploadImagePart(imageBuffer, fileName, mediaType, _finderUsername, taskId, fileSize, uin, authKey, uploadId, partNumber = 1) {
|
|
16263
|
-
const md5Hash = calculatePartialMd5(imageBuffer);
|
|
16264
|
-
const headers = {
|
|
16265
|
-
"Content-MD5": md5Hash,
|
|
16266
|
-
"X-Arguments": `apptype=251&filetype=${mediaType}&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=0`,
|
|
16267
|
-
Authorization: authKey,
|
|
16268
|
-
"Content-Type": "application/octet-stream",
|
|
16269
|
-
Referer: "https://channels.weixin.qq.com/platform/post/create",
|
|
16270
|
-
Origin: "https://channels.weixin.qq.com",
|
|
16271
|
-
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
|
16272
|
-
};
|
|
16273
|
-
const url = `https://finderassistancea.video.qq.com/uploadpartdfs?PartNumber=${partNumber}&UploadID=${encodeURIComponent(uploadId)}`;
|
|
16274
|
-
const response = await external_axios_default().put(url, imageBuffer, {
|
|
16275
|
-
headers
|
|
16452
|
+
async function uploadImageComplete(imagePath, taskId, finderUsername, uin, authKey) {
|
|
16453
|
+
const uploader = new VideoChannelUploader({
|
|
16454
|
+
chunkSize: 8388608,
|
|
16455
|
+
concurrentLimit: 4
|
|
16276
16456
|
});
|
|
16277
|
-
|
|
16278
|
-
|
|
16279
|
-
}
|
|
16280
|
-
async function getUploadedImageInfo(partInfo, _finderUsername, fileName, uploadId, fileSize, taskId, uin, authKey, mediaType) {
|
|
16281
|
-
const headers = {
|
|
16282
|
-
"Content-MD5": "null",
|
|
16283
|
-
"X-Arguments": `apptype=251&filetype=${mediaType}&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=0`,
|
|
16284
|
-
Authorization: authKey,
|
|
16285
|
-
Referer: "https://channels.weixin.qq.com/platform/post/create",
|
|
16286
|
-
Origin: "https://channels.weixin.qq.com",
|
|
16287
|
-
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
|
16288
|
-
};
|
|
16289
|
-
const requestBody = {
|
|
16290
|
-
TransFlag: "0_0",
|
|
16291
|
-
PartInfo: partInfo
|
|
16292
|
-
};
|
|
16293
|
-
const url = `https://finderassistancea.video.qq.com/completepartuploaddfs?UploadID=${encodeURIComponent(uploadId)}`;
|
|
16294
|
-
const response = await external_axios_default().post(url, requestBody, {
|
|
16295
|
-
headers
|
|
16457
|
+
const result = await uploader.upload(imagePath, uin, authKey, {
|
|
16458
|
+
onProgress: (p)=>console.log(`上传进度: ${p.percent}%`)
|
|
16296
16459
|
});
|
|
16297
|
-
return
|
|
16298
|
-
|
|
16299
|
-
|
|
16300
|
-
|
|
16301
|
-
|
|
16302
|
-
|
|
16303
|
-
|
|
16304
|
-
};
|
|
16305
|
-
if (imageBuffer.length > 5242880) return {
|
|
16306
|
-
errMsg: `图片大小超限制5MB: ${imagePath}`
|
|
16307
|
-
};
|
|
16308
|
-
const fileName = external_node_path_default().basename(imagePath);
|
|
16309
|
-
const fileSize = imageBuffer.length;
|
|
16310
|
-
const uploadIdResponse = await getUploadId(fileSize, fileName, finderUsername, taskId, uin, authKey, 20304);
|
|
16311
|
-
console.log("申请上传ID响应SSS:", JSON.stringify(uploadIdResponse));
|
|
16312
|
-
if (!uploadIdResponse.UploadID) return {
|
|
16313
|
-
errMsg: `获取上传id失败: ${uploadIdResponse.errMsg}`
|
|
16314
|
-
};
|
|
16315
|
-
const uploadResponse = await uploadImagePart(imageBuffer, fileName, 20304, finderUsername, taskId, fileSize, uin, authKey, uploadIdResponse.UploadID);
|
|
16316
|
-
if (!uploadResponse.ETag) return {
|
|
16317
|
-
errMsg: `上传图片失败: ${uploadResponse.errMsg}`
|
|
16318
|
-
};
|
|
16319
|
-
const partInfo = [
|
|
16320
|
-
{
|
|
16321
|
-
PartNumber: 1,
|
|
16322
|
-
ETag: uploadResponse.ETag
|
|
16323
|
-
}
|
|
16324
|
-
];
|
|
16325
|
-
const imageInfo = await getUploadedImageInfo(partInfo, finderUsername, fileName, uploadIdResponse.UploadID, fileSize, taskId, uin, authKey, 20304);
|
|
16326
|
-
if (!imageInfo.DownloadURL) return {
|
|
16327
|
-
errMsg: `获取图片信息失败: ${imageInfo.errMsg}`
|
|
16328
|
-
};
|
|
16329
|
-
const md5 = calculateBufferMd5(imageBuffer);
|
|
16330
|
-
return {
|
|
16331
|
-
DownloadURL: imageInfo.DownloadURL,
|
|
16332
|
-
md5
|
|
16333
|
-
};
|
|
16334
|
-
} catch (error) {
|
|
16335
|
-
return {
|
|
16336
|
-
errMsg: error instanceof Error ? error.message : "上传图片失败"
|
|
16337
|
-
};
|
|
16338
|
-
}
|
|
16460
|
+
return {
|
|
16461
|
+
DownloadURL: result.downloadUrl,
|
|
16462
|
+
md5: result.md5,
|
|
16463
|
+
fileSize: result.fileSize,
|
|
16464
|
+
width: result.width,
|
|
16465
|
+
height: result.height
|
|
16466
|
+
};
|
|
16339
16467
|
}
|
|
16340
16468
|
function buildLocation(address) {
|
|
16341
16469
|
if (!address || !address.city) return {
|
|
@@ -16407,7 +16535,7 @@ var __webpack_exports__ = {};
|
|
|
16407
16535
|
const topicList = params.topic || [];
|
|
16408
16536
|
const location1 = params.address ? buildLocation(params.address) : {};
|
|
16409
16537
|
const publishData = {
|
|
16410
|
-
clientid:
|
|
16538
|
+
clientid: generateUUID(),
|
|
16411
16539
|
timestamp: mock_getTimeStamp(13),
|
|
16412
16540
|
_log_finder_id: params.finderUsername,
|
|
16413
16541
|
_log_finder_uin: "",
|
|
@@ -16449,7 +16577,7 @@ var __webpack_exports__ = {};
|
|
|
16449
16577
|
}
|
|
16450
16578
|
}
|
|
16451
16579
|
};
|
|
16452
|
-
if (params.scheduledPublish) publishData.effectiveTime =
|
|
16580
|
+
if (params.scheduledPublish) publishData.effectiveTime = params.scheduledPublish;
|
|
16453
16581
|
const objectDesc = publishData.objectDesc;
|
|
16454
16582
|
if (topicList.length) objectDesc.topic = {
|
|
16455
16583
|
finderTopicInfo: buildTopicXml(params.content, topicList)
|
|
@@ -16489,6 +16617,7 @@ var __webpack_exports__ = {};
|
|
|
16489
16617
|
_pageUrl: "https://channels.weixin.qq.com/micro/content/post/finderNewLifeCreate"
|
|
16490
16618
|
};
|
|
16491
16619
|
const queryString = new URLSearchParams(queryData).toString();
|
|
16620
|
+
console.log("1111111111111111", JSON.stringify(requestBody));
|
|
16492
16621
|
const apiResponse = await external_axios_default().post(`${publishUrl}?${queryString}`, requestBody, {
|
|
16493
16622
|
headers: {
|
|
16494
16623
|
cookie: cookies,
|
|
@@ -16525,7 +16654,8 @@ var __webpack_exports__ = {};
|
|
|
16525
16654
|
if (0 !== authKeyResponse.errCode || !authKeyResponse.data?.authKey) return (0, share_namespaceObject.response)(authKeyResponse.errCode || 500, `获取上传认证参数失败: ${authKeyResponse.errMsg}`, "");
|
|
16526
16655
|
const authKey = authKeyResponse.data.authKey;
|
|
16527
16656
|
const uin = authKeyResponse.data.uin;
|
|
16528
|
-
|
|
16657
|
+
if (!uin) return (0, share_namespaceObject.response)(500, "获取用户 uin 失败", "");
|
|
16658
|
+
const taskId = String(generateUUID());
|
|
16529
16659
|
task.logger.info(`开始上传 ${images.length} 张图片...`);
|
|
16530
16660
|
const uploadedImages = [];
|
|
16531
16661
|
for(let i = 0; i < images.length; i++){
|
|
@@ -16536,11 +16666,11 @@ var __webpack_exports__ = {};
|
|
|
16536
16666
|
uploadedImages.push({
|
|
16537
16667
|
url: `https://finder.video.qq.com${uploadResult.DownloadURL.split("qq.com")[1] || ""}`,
|
|
16538
16668
|
md5sum: uploadResult.md5 || "",
|
|
16539
|
-
fileSize: 0,
|
|
16669
|
+
fileSize: uploadResult.fileSize || 0,
|
|
16540
16670
|
thumbUrl: uploadResult.DownloadURL,
|
|
16541
16671
|
fullThumbUrl: uploadResult.DownloadURL,
|
|
16542
|
-
width: 0,
|
|
16543
|
-
height: 0,
|
|
16672
|
+
width: uploadResult.width || 0,
|
|
16673
|
+
height: uploadResult.height || 0,
|
|
16544
16674
|
mediaType: 2,
|
|
16545
16675
|
videoPlayLen: 0,
|
|
16546
16676
|
urlCdnTaskId: ""
|
|
@@ -16565,6 +16695,7 @@ var __webpack_exports__ = {};
|
|
|
16565
16695
|
topic: topicNames,
|
|
16566
16696
|
link: params.link,
|
|
16567
16697
|
address: addressInfo,
|
|
16698
|
+
collection: params.collection,
|
|
16568
16699
|
scheduledPublish: params.scheduledPublish,
|
|
16569
16700
|
music: params.music
|
|
16570
16701
|
});
|
|
@@ -16741,12 +16872,12 @@ var __webpack_exports__ = {};
|
|
|
16741
16872
|
task.logger.info("内容填写完成");
|
|
16742
16873
|
});
|
|
16743
16874
|
}
|
|
16744
|
-
if (params.address) {
|
|
16875
|
+
if (params.address?.poi_id) {
|
|
16745
16876
|
task.logger.info(`选择地点: ${params.address.name}`);
|
|
16746
16877
|
const instance = page.locator(".position-display-wrap");
|
|
16747
16878
|
await instance.click();
|
|
16748
16879
|
await page.waitForTimeout(1000);
|
|
16749
|
-
await page.locator(".location-filter-wrap input").fill(params.address.
|
|
16880
|
+
await page.locator(".location-filter-wrap input").fill(params.address?.name || params.address?.address || params.address?.city_name);
|
|
16750
16881
|
await page.waitForTimeout(2000);
|
|
16751
16882
|
const poperInstance = page.locator(".location-filter-wrap .common-option-list-wrap .option-item");
|
|
16752
16883
|
await poperInstance.nth(1).waitFor();
|
|
@@ -16769,7 +16900,7 @@ var __webpack_exports__ = {};
|
|
|
16769
16900
|
await instanceLink.first().click();
|
|
16770
16901
|
task.logger.info(`添加链接: ${params.link.link}`);
|
|
16771
16902
|
await page.waitForTimeout(500);
|
|
16772
|
-
const linkTypeName =
|
|
16903
|
+
const linkTypeName = 1 === params.link.urlType ? "公众号文章" : "红包封面";
|
|
16773
16904
|
page.locator(".post-link-wrap .link-list-options .link-option-item").filter({
|
|
16774
16905
|
hasText: linkTypeName
|
|
16775
16906
|
}).first().click({
|
|
@@ -16864,6 +16995,384 @@ var __webpack_exports__ = {};
|
|
|
16864
16995
|
return (0, share_namespaceObject.response)(500, `微信视频号发布失败: ${errorMsg}`, "");
|
|
16865
16996
|
}
|
|
16866
16997
|
};
|
|
16998
|
+
const rpaAction_Server = async (task, params)=>{
|
|
16999
|
+
task.logger.info("开始微信视频号发布(Server 模式)");
|
|
17000
|
+
const defaultPage = task.steelBrowserContext?.pages()[0];
|
|
17001
|
+
if (defaultPage) {
|
|
17002
|
+
if (!defaultPage._routeRegistered) {
|
|
17003
|
+
defaultPage._routeRegistered = true;
|
|
17004
|
+
const blockedPatterns = [
|
|
17005
|
+
"**/apm-fe.weixin.com*",
|
|
17006
|
+
"**/t2.weixin.com*"
|
|
17007
|
+
].map((pattern)=>new RegExp(pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")));
|
|
17008
|
+
await defaultPage.route("**/*", async (route)=>{
|
|
17009
|
+
const req = route.request();
|
|
17010
|
+
const url = req.url();
|
|
17011
|
+
const blocked = blockedPatterns.some((regex)=>regex.test(url));
|
|
17012
|
+
if (!blocked) return route.continue();
|
|
17013
|
+
if ("OPTIONS" === req.method()) {
|
|
17014
|
+
console.log("处理 OPTIONS 预检:", url);
|
|
17015
|
+
await route.fulfill({
|
|
17016
|
+
status: 204,
|
|
17017
|
+
headers: {
|
|
17018
|
+
"access-control-allow-origin": "*",
|
|
17019
|
+
"access-control-allow-methods": "GET,POST,OPTIONS,PUT,DELETE",
|
|
17020
|
+
"access-control-allow-headers": "*"
|
|
17021
|
+
},
|
|
17022
|
+
body: ""
|
|
17023
|
+
});
|
|
17024
|
+
return;
|
|
17025
|
+
}
|
|
17026
|
+
await route.fulfill({
|
|
17027
|
+
status: 204,
|
|
17028
|
+
body: ""
|
|
17029
|
+
});
|
|
17030
|
+
});
|
|
17031
|
+
}
|
|
17032
|
+
}
|
|
17033
|
+
const tmpCachePath = task.getTmpPath();
|
|
17034
|
+
task.logger?.info("==>进入RPA操作:任务开始,下载图片开始...");
|
|
17035
|
+
const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
|
|
17036
|
+
const imagePromise = Promise.all(params.banners.map((url)=>{
|
|
17037
|
+
const fileName = (0, share_namespaceObject.getFilenameFromUrl)(url);
|
|
17038
|
+
return (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
|
|
17039
|
+
}));
|
|
17040
|
+
let proxyUrl;
|
|
17041
|
+
if (params.localIP) {
|
|
17042
|
+
const args = [
|
|
17043
|
+
params.localIP,
|
|
17044
|
+
params.proxyLoc,
|
|
17045
|
+
params.accountId
|
|
17046
|
+
];
|
|
17047
|
+
task.logger?.info(`==> 开始获取代理信息:${args}`);
|
|
17048
|
+
const ProxyAgentResult = await ProxyAgent({
|
|
17049
|
+
logger: task.logger
|
|
17050
|
+
}, ...args);
|
|
17051
|
+
task.logger?.info("==> 代理信息获取成功!");
|
|
17052
|
+
proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
|
|
17053
|
+
}
|
|
17054
|
+
task.logger?.info("==>开始打开视频号页面...");
|
|
17055
|
+
const page = await task.createPage({
|
|
17056
|
+
show: task.debug,
|
|
17057
|
+
cookies: params.cookies,
|
|
17058
|
+
proxyUrl,
|
|
17059
|
+
url: params.url || "https://channels.weixin.qq.com/platform/post/finderNewLifeCreate",
|
|
17060
|
+
...params.viewport ? {
|
|
17061
|
+
viewport: params.viewport
|
|
17062
|
+
} : {}
|
|
17063
|
+
});
|
|
17064
|
+
task.logger?.info("==>视频号页面打开成功");
|
|
17065
|
+
console.log(task.steelConnector?.getLive(task.sessionId || ""));
|
|
17066
|
+
await updateTaskState?.({
|
|
17067
|
+
state: share_namespaceObject.TaskState.ACTION,
|
|
17068
|
+
connectAddress: task.steelConnector?.getProxyUrl(task.sessionId || "", "v1/sessions/debug"),
|
|
17069
|
+
sessionId: task.sessionId
|
|
17070
|
+
});
|
|
17071
|
+
const clickTimeout = 10000;
|
|
17072
|
+
try {
|
|
17073
|
+
await page.waitForSelector(".post-edit-wrap", {
|
|
17074
|
+
state: "visible",
|
|
17075
|
+
timeout: 10000
|
|
17076
|
+
});
|
|
17077
|
+
task.logger?.info("✓ 登录状态正常,找到编辑器容器");
|
|
17078
|
+
} catch (error) {
|
|
17079
|
+
task.logger?.error("✗ 未找到编辑器,可能登录失效");
|
|
17080
|
+
return {
|
|
17081
|
+
code: 414,
|
|
17082
|
+
message: "登录失效或页面加载异常",
|
|
17083
|
+
data: page.url()
|
|
17084
|
+
};
|
|
17085
|
+
}
|
|
17086
|
+
const images = await imagePromise;
|
|
17087
|
+
task.logger?.info(`==>图片下载完成,共 ${images.length} 张,开始上传图片...`);
|
|
17088
|
+
const uploadSelectors = [
|
|
17089
|
+
'.ant-upload-btn input[type="file"]',
|
|
17090
|
+
'.upload input[type="file"][accept*="image"]',
|
|
17091
|
+
'.upload-wrap input[type="file"]',
|
|
17092
|
+
'input[type="file"][accept*="image"]'
|
|
17093
|
+
];
|
|
17094
|
+
let uploadInput = null;
|
|
17095
|
+
for (const selector of uploadSelectors){
|
|
17096
|
+
const input = page.locator(selector);
|
|
17097
|
+
const count = await input.count();
|
|
17098
|
+
if (count > 0) {
|
|
17099
|
+
uploadInput = input.first();
|
|
17100
|
+
task.logger?.info(`找到上传输入框: ${selector}`);
|
|
17101
|
+
break;
|
|
17102
|
+
}
|
|
17103
|
+
}
|
|
17104
|
+
if (!uploadInput) {
|
|
17105
|
+
task.logger?.warn("未找到上传输入框,等待 3 秒后重试...");
|
|
17106
|
+
await page.waitForTimeout(3000);
|
|
17107
|
+
const anyFileInput = page.locator('input[type="file"]');
|
|
17108
|
+
const inputCount = await anyFileInput.count();
|
|
17109
|
+
if (inputCount > 0) {
|
|
17110
|
+
uploadInput = anyFileInput.first();
|
|
17111
|
+
task.logger?.info(`找到文件输入框(共 ${inputCount} 个)`);
|
|
17112
|
+
} else {
|
|
17113
|
+
if (task.debug) {
|
|
17114
|
+
const screenshotPath = external_node_path_default().join(tmpCachePath, `upload-error-${Date.now()}.png`);
|
|
17115
|
+
await page.screenshot({
|
|
17116
|
+
path: screenshotPath,
|
|
17117
|
+
fullPage: true
|
|
17118
|
+
});
|
|
17119
|
+
task.logger?.error(`未找到上传输入框,已截图保存至: ${screenshotPath}`);
|
|
17120
|
+
}
|
|
17121
|
+
throw new Error("未找到图片上传输入框");
|
|
17122
|
+
}
|
|
17123
|
+
}
|
|
17124
|
+
await uploadInput.setInputFiles(images, {
|
|
17125
|
+
timeout: 60000
|
|
17126
|
+
});
|
|
17127
|
+
task.logger?.info(`==>图片上传完成: ${images.length} 张`);
|
|
17128
|
+
await page.waitForTimeout(3000);
|
|
17129
|
+
if (params.title) {
|
|
17130
|
+
task.logger?.info(`填写标题: ${params.title}`);
|
|
17131
|
+
const titleInput = page.locator('input[placeholder*="填写标题"]');
|
|
17132
|
+
await titleInput.waitFor({
|
|
17133
|
+
state: "visible",
|
|
17134
|
+
timeout: clickTimeout
|
|
17135
|
+
});
|
|
17136
|
+
await titleInput.click({
|
|
17137
|
+
timeout: clickTimeout
|
|
17138
|
+
});
|
|
17139
|
+
await titleInput.clear({
|
|
17140
|
+
timeout: 3000
|
|
17141
|
+
});
|
|
17142
|
+
await titleInput.fill(params.title, {
|
|
17143
|
+
timeout: 5000
|
|
17144
|
+
});
|
|
17145
|
+
task.logger?.info("==>标题填写完成");
|
|
17146
|
+
}
|
|
17147
|
+
if (params.content) {
|
|
17148
|
+
task.logger?.info("填写描述和话题");
|
|
17149
|
+
const descEditor = page.locator(".input-editor");
|
|
17150
|
+
await descEditor.waitFor({
|
|
17151
|
+
state: "visible",
|
|
17152
|
+
timeout: clickTimeout
|
|
17153
|
+
});
|
|
17154
|
+
await descEditor.click({
|
|
17155
|
+
timeout: clickTimeout
|
|
17156
|
+
});
|
|
17157
|
+
await page.waitForTimeout(500);
|
|
17158
|
+
await descEditor.evaluate((el)=>{
|
|
17159
|
+
el.textContent = "";
|
|
17160
|
+
});
|
|
17161
|
+
await page.waitForTimeout(300);
|
|
17162
|
+
task.logger?.info("已清空编辑器内容");
|
|
17163
|
+
await descEditor.pressSequentially(params.content, {
|
|
17164
|
+
delay: 10
|
|
17165
|
+
});
|
|
17166
|
+
await page.waitForTimeout(500);
|
|
17167
|
+
task.logger?.info("==>内容填写完成");
|
|
17168
|
+
}
|
|
17169
|
+
if (params.address?.poi_id) {
|
|
17170
|
+
task.logger?.info(`选择地点: ${params.address.name}`);
|
|
17171
|
+
const positionDisplayWrap = page.locator(".position-display-wrap");
|
|
17172
|
+
await positionDisplayWrap.click({
|
|
17173
|
+
timeout: clickTimeout
|
|
17174
|
+
});
|
|
17175
|
+
await page.waitForTimeout(1000);
|
|
17176
|
+
await page.locator(".location-filter-wrap input").fill(params.address?.name || params.address?.address || params.address?.city_name);
|
|
17177
|
+
await page.waitForTimeout(2000);
|
|
17178
|
+
const poperInstance = page.locator(".location-filter-wrap .common-option-list-wrap .option-item");
|
|
17179
|
+
await poperInstance.nth(1).waitFor();
|
|
17180
|
+
await poperInstance.nth(1).click({
|
|
17181
|
+
timeout: clickTimeout
|
|
17182
|
+
});
|
|
17183
|
+
task.logger?.info("==>地点选择完成");
|
|
17184
|
+
}
|
|
17185
|
+
if (params.collection) {
|
|
17186
|
+
task.logger?.info(`选择合集: ${params.collection.collectionName}`);
|
|
17187
|
+
const instanceCollection = page.locator(".post-album-display-wrap");
|
|
17188
|
+
await instanceCollection.click({
|
|
17189
|
+
timeout: clickTimeout
|
|
17190
|
+
});
|
|
17191
|
+
await page.waitForTimeout(1000);
|
|
17192
|
+
await page.locator(".post-album-wrap .option-item").filter({
|
|
17193
|
+
hasText: params.collection.collectionName
|
|
17194
|
+
}).first().click({
|
|
17195
|
+
force: true
|
|
17196
|
+
});
|
|
17197
|
+
task.logger?.info("==>合集选择完成");
|
|
17198
|
+
}
|
|
17199
|
+
if (params.link) {
|
|
17200
|
+
task.logger?.info(`添加链接: ${params.link.link}`);
|
|
17201
|
+
const instanceLink = page.locator(".link-display-wrap");
|
|
17202
|
+
await instanceLink.first().click({
|
|
17203
|
+
timeout: clickTimeout
|
|
17204
|
+
});
|
|
17205
|
+
await page.waitForTimeout(500);
|
|
17206
|
+
const linkTypeName = 1 === params.link.urlType ? "公众号文章" : "红包封面";
|
|
17207
|
+
await page.locator(".post-link-wrap .link-list-options .link-option-item").filter({
|
|
17208
|
+
hasText: linkTypeName
|
|
17209
|
+
}).first().click({
|
|
17210
|
+
force: true
|
|
17211
|
+
});
|
|
17212
|
+
await page.waitForSelector(".link-input-wrap", {
|
|
17213
|
+
state: "visible",
|
|
17214
|
+
timeout: 3000
|
|
17215
|
+
});
|
|
17216
|
+
const linkInput = page.locator('.link-input-wrap input[type="text"]');
|
|
17217
|
+
await linkInput.first().fill(params.link.link);
|
|
17218
|
+
task.logger?.info("==>链接添加完成");
|
|
17219
|
+
}
|
|
17220
|
+
if (params.music) {
|
|
17221
|
+
task.logger?.info(`添加背景音乐: ${params.music.name}`);
|
|
17222
|
+
const musicFormItem = page.locator(".post-with-link").filter({
|
|
17223
|
+
hasText: "音乐"
|
|
17224
|
+
});
|
|
17225
|
+
const musicDisplayWrap = musicFormItem.locator(".link-display-wrap").first();
|
|
17226
|
+
await musicDisplayWrap.click({
|
|
17227
|
+
timeout: clickTimeout
|
|
17228
|
+
});
|
|
17229
|
+
const searchInput = musicFormItem.locator('.weui-desktop-search input[type="text"]').first();
|
|
17230
|
+
const searchTxt = `${params.music.name} - ${params.music.authorName}`;
|
|
17231
|
+
await searchInput.fill(searchTxt);
|
|
17232
|
+
await page.waitForTimeout(300);
|
|
17233
|
+
await searchInput.press("Enter");
|
|
17234
|
+
await page.waitForTimeout(2000);
|
|
17235
|
+
const bgmItemWrap = musicFormItem.locator(".bgm-item-wrap").filter({
|
|
17236
|
+
hasText: searchTxt
|
|
17237
|
+
}).first();
|
|
17238
|
+
await bgmItemWrap.hover();
|
|
17239
|
+
await page.waitForTimeout(500);
|
|
17240
|
+
await bgmItemWrap.locator(".selected-icon").first().click({
|
|
17241
|
+
force: true
|
|
17242
|
+
});
|
|
17243
|
+
task.logger?.info("==>背景音乐添加完成");
|
|
17244
|
+
}
|
|
17245
|
+
if (!params.isImmediatelyPublish && params.scheduledPublish) {
|
|
17246
|
+
task.logger?.info("设置定时发布");
|
|
17247
|
+
const timingRadio = page.locator(".weui-desktop-form__check-content").filter({
|
|
17248
|
+
hasNotText: "不定时"
|
|
17249
|
+
}).first();
|
|
17250
|
+
await timingRadio.click({
|
|
17251
|
+
timeout: clickTimeout
|
|
17252
|
+
});
|
|
17253
|
+
await page.waitForTimeout(500);
|
|
17254
|
+
const dateInput = page.locator('.weui-desktop-picker__date input[placeholder*="请选择发表时间"]');
|
|
17255
|
+
await dateInput.click({
|
|
17256
|
+
timeout: clickTimeout
|
|
17257
|
+
});
|
|
17258
|
+
const dateD = utils_TimeFormatter.format(params.scheduledPublish, "d");
|
|
17259
|
+
const nowMonth = utils_TimeFormatter.format(Date.now(), "MM月");
|
|
17260
|
+
const nowMonthText = utils_TimeFormatter.format(Date.now(), "M月");
|
|
17261
|
+
const month = utils_TimeFormatter.format(params.scheduledPublish, "MM月");
|
|
17262
|
+
const monthLocator = page.locator("weui-desktop-picker__panel__label").filter({
|
|
17263
|
+
hasText: month
|
|
17264
|
+
}).first();
|
|
17265
|
+
const monthCount = await monthLocator.count();
|
|
17266
|
+
if (0 === monthCount) {
|
|
17267
|
+
await page.locator(".weui-desktop-picker__panel__label").filter({
|
|
17268
|
+
hasText: nowMonth
|
|
17269
|
+
}).first().click({
|
|
17270
|
+
timeout: clickTimeout
|
|
17271
|
+
});
|
|
17272
|
+
await page.waitForTimeout(500);
|
|
17273
|
+
await page.locator(".weui-desktop-picker__table-row td a").filter({
|
|
17274
|
+
hasText: nowMonthText
|
|
17275
|
+
}).first().click({
|
|
17276
|
+
timeout: clickTimeout
|
|
17277
|
+
});
|
|
17278
|
+
}
|
|
17279
|
+
await page.waitForTimeout(500);
|
|
17280
|
+
await page.locator(".weui-desktop-picker__table-row td a").filter({
|
|
17281
|
+
hasText: dateD
|
|
17282
|
+
}).first().click({
|
|
17283
|
+
timeout: clickTimeout
|
|
17284
|
+
});
|
|
17285
|
+
await page.locator(".weui-desktop-form__input-wrp input[placeholder*='请选择时间']").fill(utils_TimeFormatter.format(params.scheduledPublish, "hh:mm"));
|
|
17286
|
+
await page.locator("i.weui-desktop-icon__time").click({
|
|
17287
|
+
timeout: clickTimeout
|
|
17288
|
+
});
|
|
17289
|
+
await page.locator(".post-time-wrap .form-item .label").filter({
|
|
17290
|
+
hasText: "发表时间"
|
|
17291
|
+
}).click({
|
|
17292
|
+
timeout: clickTimeout
|
|
17293
|
+
});
|
|
17294
|
+
task.logger?.info("==>定时发布设置完成");
|
|
17295
|
+
}
|
|
17296
|
+
task.logger?.info("准备发布...");
|
|
17297
|
+
await page.waitForTimeout(300);
|
|
17298
|
+
if (MockPublish) {
|
|
17299
|
+
const message = "视频号模拟发布成功";
|
|
17300
|
+
const data = "123456789";
|
|
17301
|
+
await updateTaskState?.({
|
|
17302
|
+
state: share_namespaceObject.TaskState.SUCCESS,
|
|
17303
|
+
result: {
|
|
17304
|
+
response: data
|
|
17305
|
+
}
|
|
17306
|
+
});
|
|
17307
|
+
return (0, share_namespaceObject.success)(data, message);
|
|
17308
|
+
}
|
|
17309
|
+
const publishResponse = await new Promise((resolve)=>{
|
|
17310
|
+
const handleResponse = async (response)=>{
|
|
17311
|
+
const url = response.url();
|
|
17312
|
+
if (url.includes("/post/post_create") || url.includes("/post/post_draft")) {
|
|
17313
|
+
const jsonResponse = await response.json();
|
|
17314
|
+
page.off("response", handleResponse);
|
|
17315
|
+
const articleId = jsonResponse.object?.id || jsonResponse.data?.objectId || "";
|
|
17316
|
+
const message = jsonResponse?.errMsg || "";
|
|
17317
|
+
const errCode = jsonResponse.data?.baseResp?.errcode ?? jsonResponse.errCode;
|
|
17318
|
+
if (0 === errCode) resolve({
|
|
17319
|
+
success: true,
|
|
17320
|
+
msg: message || "发布成功",
|
|
17321
|
+
data: {
|
|
17322
|
+
id: articleId,
|
|
17323
|
+
objectId: articleId
|
|
17324
|
+
}
|
|
17325
|
+
});
|
|
17326
|
+
else {
|
|
17327
|
+
let errorMessage = message;
|
|
17328
|
+
if (-11224 === errCode) errorMessage = "视频号管理员完成实名且绑定手机号后才可以发表";
|
|
17329
|
+
else if (300333 === errCode || 300334 === errCode) errorMessage = "登录失效";
|
|
17330
|
+
else if (300330 === errCode) errorMessage = "未登录";
|
|
17331
|
+
else if (300002 === errCode) errorMessage = "官方平台在校验音乐/位置/定时信息时失败了,请重新编辑后发布";
|
|
17332
|
+
resolve({
|
|
17333
|
+
success: false,
|
|
17334
|
+
msg: errorMessage
|
|
17335
|
+
});
|
|
17336
|
+
}
|
|
17337
|
+
}
|
|
17338
|
+
};
|
|
17339
|
+
page.on("response", handleResponse);
|
|
17340
|
+
const publishText = "1" === params.publishType ? "发表" : "保存草稿";
|
|
17341
|
+
page.locator(".form-btns .weui-desktop-btn").filter({
|
|
17342
|
+
hasText: publishText
|
|
17343
|
+
}).first().click({
|
|
17344
|
+
timeout: clickTimeout
|
|
17345
|
+
});
|
|
17346
|
+
setTimeout(()=>{
|
|
17347
|
+
page.off("response", handleResponse);
|
|
17348
|
+
resolve({
|
|
17349
|
+
success: false,
|
|
17350
|
+
msg: "发布超时"
|
|
17351
|
+
});
|
|
17352
|
+
}, 10000);
|
|
17353
|
+
});
|
|
17354
|
+
if (!publishResponse?.success) {
|
|
17355
|
+
const msg = `发布失败:${publishResponse?.msg || "未知错误"}`;
|
|
17356
|
+
await updateTaskState?.({
|
|
17357
|
+
state: share_namespaceObject.TaskState.FAILED,
|
|
17358
|
+
error: msg
|
|
17359
|
+
});
|
|
17360
|
+
await page.close();
|
|
17361
|
+
return {
|
|
17362
|
+
code: 414,
|
|
17363
|
+
message: msg,
|
|
17364
|
+
data: ""
|
|
17365
|
+
};
|
|
17366
|
+
}
|
|
17367
|
+
await updateTaskState?.({
|
|
17368
|
+
state: share_namespaceObject.TaskState.SUCCESS,
|
|
17369
|
+
result: {
|
|
17370
|
+
response: publishResponse?.data?.id || ""
|
|
17371
|
+
}
|
|
17372
|
+
});
|
|
17373
|
+
await page.close();
|
|
17374
|
+
return (0, share_namespaceObject.success)(publishResponse?.data?.id || "", publishResponse?.msg || "发布成功");
|
|
17375
|
+
};
|
|
16867
17376
|
const ShipinhaoPublishParamsSchema = ActionCommonParamsSchema.extend({
|
|
16868
17377
|
title: schemas_string(),
|
|
16869
17378
|
content: schemas_string(),
|
|
@@ -16871,19 +17380,14 @@ var __webpack_exports__ = {};
|
|
|
16871
17380
|
topic: schemas_array(schemas_string()).optional(),
|
|
16872
17381
|
address: schemas_object({
|
|
16873
17382
|
poi_id: schemas_string(),
|
|
16874
|
-
name: schemas_string(),
|
|
16875
|
-
address: schemas_string(),
|
|
17383
|
+
name: schemas_string().optional(),
|
|
17384
|
+
address: schemas_string().optional(),
|
|
16876
17385
|
latitude: schemas_number(),
|
|
16877
17386
|
longitude: schemas_number(),
|
|
16878
|
-
city_name: schemas_string()
|
|
16879
|
-
poi_type: schemas_number(),
|
|
16880
|
-
type: schemas_string()
|
|
17387
|
+
city_name: schemas_string()
|
|
16881
17388
|
}).optional(),
|
|
16882
17389
|
link: schemas_object({
|
|
16883
|
-
urlType:
|
|
16884
|
-
"1",
|
|
16885
|
-
"2"
|
|
16886
|
-
]),
|
|
17390
|
+
urlType: schemas_number(),
|
|
16887
17391
|
link: schemas_string(),
|
|
16888
17392
|
title: schemas_string()
|
|
16889
17393
|
}).optional(),
|
|
@@ -16918,7 +17422,8 @@ var __webpack_exports__ = {};
|
|
|
16918
17422
|
console.log("shipinhaoPublish params:", params);
|
|
16919
17423
|
if ("rpa" === params.actionType) return shipinhaoPublish_rpa_rpaAction(task, params);
|
|
16920
17424
|
if ("mockApi" === params.actionType) return shipinhaoPublish_mock_mockAction(task, params);
|
|
16921
|
-
|
|
17425
|
+
if ("server" === params.actionType) return rpaAction_Server(task, params);
|
|
17426
|
+
return executeAction(shipinhaoPublish_mock_mockAction, rpaAction_Server)(task, params);
|
|
16922
17427
|
};
|
|
16923
17428
|
const toutiaoLogin_rpa_scanRetryMaxCount = 60;
|
|
16924
17429
|
const toutiaoLogin_rpa_waitQrcodeResultMaxTime = 2000 * toutiaoLogin_rpa_scanRetryMaxCount;
|
|
@@ -20845,7 +21350,7 @@ var __webpack_exports__ = {};
|
|
|
20845
21350
|
await page.close();
|
|
20846
21351
|
return (0, share_namespaceObject.success)(response);
|
|
20847
21352
|
};
|
|
20848
|
-
const
|
|
21353
|
+
const rpa_server_rpaAction_Server = async (task, params)=>{
|
|
20849
21354
|
if (params.originalBind && params?.selfDeclaration?.type === "source-statement") return {
|
|
20850
21355
|
code: 414,
|
|
20851
21356
|
message: "已声明原创不可选择“来源转载”",
|
|
@@ -21728,8 +22233,8 @@ var __webpack_exports__ = {};
|
|
|
21728
22233
|
const xiaohongshuPublish = async (task, params)=>{
|
|
21729
22234
|
if ("rpa" === params.actionType) return xiaohongshuPublish_rpa_rpaAction(task, params);
|
|
21730
22235
|
if ("mockApi" === params.actionType) return xiaohongshuPublish_mock_mockAction(task, params);
|
|
21731
|
-
if ("server" === params.actionType) return
|
|
21732
|
-
return executeAction(xiaohongshuPublish_mock_mockAction, rpaAction_Server_Mock,
|
|
22236
|
+
if ("server" === params.actionType) return rpa_server_rpaAction_Server(task, params);
|
|
22237
|
+
return executeAction(xiaohongshuPublish_mock_mockAction, rpaAction_Server_Mock, rpa_server_rpaAction_Server)(task, params);
|
|
21733
22238
|
};
|
|
21734
22239
|
const xiaohongshuWebCommentAction_xsEncrypt = new Xhshow();
|
|
21735
22240
|
const xiaohongshuWebCommentAction = async (_task, params)=>{
|