@iflyrpa/actions 4.0.4-beta.0 → 4.0.4-beta.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/index.d.ts CHANGED
@@ -292,6 +292,22 @@ export declare class Action {
292
292
  readNumYesterday: number | null;
293
293
  likeNumYesterday: number | null;
294
294
  commentNumYesterday: number | null;
295
+ } | {
296
+ fansNum: number;
297
+ favedNum: number;
298
+ fansNumLastWeek: number;
299
+ watchNumLastWeek: number;
300
+ likeNumLastWeek: number;
301
+ commentNumLastWeek: number;
302
+ shareNumLastWeek: number;
303
+ visitNumLastWeek: number;
304
+ } | {
305
+ fansNum: number;
306
+ feedsCount: number;
307
+ fansNumYesterday: number | null;
308
+ playNumYesterday: number | null;
309
+ likeNumYesterday: number | null;
310
+ commentNumYesterday: number | null;
295
311
  } | null>>;
296
312
  TTSessionCheck(params: ActiomCommonParams): Promise<ResponseData<{
297
313
  isValidSession: boolean;
package/dist/index.js CHANGED
@@ -4398,7 +4398,7 @@ var __webpack_exports__ = {};
4398
4398
  });
4399
4399
  const package_json_namespaceObject = require("@iflyrpa/share/package.json");
4400
4400
  var package_json_default = /*#__PURE__*/ __webpack_require__.n(package_json_namespaceObject);
4401
- var package_namespaceObject = JSON.parse('{"i8":"4.0.4-beta.0"}');
4401
+ var package_namespaceObject = JSON.parse('{"i8":"4.0.4-beta.1"}');
4402
4402
  const share_namespaceObject = require("@iflyrpa/share");
4403
4403
  const external_node_fs_namespaceObject = require("node:fs");
4404
4404
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
@@ -15359,6 +15359,199 @@ var __webpack_exports__ = {};
15359
15359
  };
15360
15360
  return (0, share_namespaceObject.success)(bjhData, "百家号平台数据获取成功!");
15361
15361
  }
15362
+ async function getDouyinData(_task, params) {
15363
+ try {
15364
+ const sessionidCookie = params.cookies.find((it)=>"sessionid" === it.name)?.value;
15365
+ if (!sessionidCookie) return types_errorResponse("抖音账号数据异常,请重新绑定账号后重试。", 414);
15366
+ const csrfToken = params.cookies.find((it)=>"passport_csrf_token" === it.name)?.value || "";
15367
+ const headers = {
15368
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
15369
+ referer: "https://creator.douyin.com/creator-micro/home",
15370
+ origin: "https://creator.douyin.com",
15371
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
15372
+ ...csrfToken ? {
15373
+ "x-secsdk-csrf-token": csrfToken
15374
+ } : {}
15375
+ };
15376
+ const args = [
15377
+ {
15378
+ headers
15379
+ },
15380
+ _task.logger,
15381
+ params.proxyLoc,
15382
+ params.localIP,
15383
+ params.accountId
15384
+ ];
15385
+ const http = new Http(...args);
15386
+ const toNum = (val)=>{
15387
+ if (null == val) return 0;
15388
+ const n = Number.parseInt(String(val).replace(/[+,]/g, ""), 10);
15389
+ return Number.isNaN(n) ? 0 : n;
15390
+ };
15391
+ const userProfileP = http.api({
15392
+ method: "get",
15393
+ url: "https://www.douyin.com/aweme/v1/web/user/profile/self/",
15394
+ params: {
15395
+ device_platform: "webapp",
15396
+ aid: "6383",
15397
+ channel: "channel_pc_web",
15398
+ pc_client_type: "1",
15399
+ version_code: "170400",
15400
+ version_name: "17.4.0",
15401
+ cookie_enabled: "true",
15402
+ platform: "PC"
15403
+ }
15404
+ }, {
15405
+ retries: 3,
15406
+ retryDelay: 100,
15407
+ timeout: 10000
15408
+ }).catch((e)=>{
15409
+ _task.logger.warn(`抖音用户信息获取失败: ${e instanceof Error ? e.message : String(e)}`);
15410
+ return null;
15411
+ });
15412
+ const overviewP = http.api({
15413
+ method: "get",
15414
+ url: "https://creator.douyin.com/aweme/janus/creator/data/overview/all/",
15415
+ params: {
15416
+ last_days_type: 1,
15417
+ aid: 2906,
15418
+ app_name: "aweme_creator_platform",
15419
+ device_platform: "web"
15420
+ }
15421
+ }, {
15422
+ retries: 3,
15423
+ retryDelay: 100,
15424
+ timeout: 5000
15425
+ }).catch((e)=>{
15426
+ _task.logger.warn(`抖音近7日数据获取失败(可能未开通数据中心或被风控): ${e instanceof Error ? e.message : String(e)}`);
15427
+ return null;
15428
+ });
15429
+ const [userProfile, overview] = await Promise.all([
15430
+ userProfileP,
15431
+ overviewP
15432
+ ]);
15433
+ _task.logger.info(`抖音用户信息响应: ${JSON.stringify(userProfile)}`);
15434
+ _task.logger.info(`抖音近7日数据响应: ${JSON.stringify(overview)}`);
15435
+ let fansNum = 0;
15436
+ let favedNum = 0;
15437
+ let followingNum = 0;
15438
+ if (userProfile?.status_code === 0 && userProfile.user) {
15439
+ const user = userProfile.user;
15440
+ fansNum = toNum(user.follower_count);
15441
+ followingNum = toNum(user.following_count);
15442
+ favedNum = toNum(user.total_favorited);
15443
+ _task.logger.info(`提取用户数据 - 昵称: ${user.nickname}, 粉丝: ${fansNum}, 关注: ${followingNum}, 获赞: ${favedNum}, 作品: ${user.aweme_count}`);
15444
+ } else _task.logger.warn(`用户信息接口返回异常: status_code=${userProfile?.status_code}, msg=${userProfile?.status_msg}`);
15445
+ const ov = overview?.data;
15446
+ const douyinData = {
15447
+ fansNum,
15448
+ favedNum,
15449
+ fansNumLastWeek: toNum(ov?.fans_incr?.current_count),
15450
+ watchNumLastWeek: toNum(ov?.play_count?.current_count),
15451
+ likeNumLastWeek: toNum(ov?.like_count?.current_count),
15452
+ commentNumLastWeek: toNum(ov?.comment_count?.current_count),
15453
+ shareNumLastWeek: toNum(ov?.share_count?.current_count),
15454
+ visitNumLastWeek: toNum(ov?.profile_visit?.current_count)
15455
+ };
15456
+ return (0, share_namespaceObject.success)(douyinData, "抖音平台数据获取成功!");
15457
+ } catch (error) {
15458
+ if (error && "object" == typeof error && "code" in error && "message" in error) {
15459
+ const err = error;
15460
+ _task.logger.error(`抖音账号数据获取失败: ${err.message} (${err.code})`);
15461
+ return types_errorResponse(err.message, err.code);
15462
+ }
15463
+ const errMsg = error instanceof Error ? error.message : String(error);
15464
+ _task.logger.error(`抖音账号数据获取失败: ${errMsg}`);
15465
+ return types_errorResponse(errMsg || "抖音账号数据获取失败");
15466
+ }
15467
+ }
15468
+ async function getShipinhaoData(_task, params) {
15469
+ try {
15470
+ const sessionidCookie = params.cookies.find((it)=>"sessionid" === it.name)?.value;
15471
+ if (!sessionidCookie) return types_errorResponse("视频号账号数据异常,请重新绑定账号后重试。", 414);
15472
+ const uinCookie = params.cookies.find((it)=>"uin" === it.name || "wxuin" === it.name)?.value || "0000000000";
15473
+ const deviceIdCookie = params.cookies.find((it)=>"device_id" === it.name || "finger_print_device_id" === it.name)?.value;
15474
+ const aid = params.cookies.find((it)=>"_aid" === it.name)?.value || "9d3e0e9f-b842-498d-a273-4285d58df264";
15475
+ const finderId = params.cookies.find((it)=>"_log_finder_id" === it.name || "finder_id" === it.name)?.value || "";
15476
+ const headers = {
15477
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
15478
+ referer: "https://channels.weixin.qq.com/platform",
15479
+ origin: "https://channels.weixin.qq.com",
15480
+ "content-type": "application/json",
15481
+ "X-WECHAT-UIN": uinCookie,
15482
+ ...deviceIdCookie ? {
15483
+ "finger-print-device-id": deviceIdCookie
15484
+ } : {}
15485
+ };
15486
+ const args = [
15487
+ {
15488
+ headers
15489
+ },
15490
+ _task.logger,
15491
+ params.proxyLoc,
15492
+ params.localIP,
15493
+ params.accountId
15494
+ ];
15495
+ const http = new Http(...args);
15496
+ const authData = await http.api({
15497
+ method: "post",
15498
+ url: "https://channels.weixin.qq.com/cgi-bin/mmfinderassistant-bin/auth/auth_data",
15499
+ params: {
15500
+ _aid: aid,
15501
+ _rid: `${Date.now().toString(16)}-${Math.random().toString(36).substring(2, 9)}`,
15502
+ _pageUrl: encodeURIComponent("https://channels.weixin.qq.com/platform")
15503
+ },
15504
+ data: {
15505
+ timestamp: Date.now().toString(),
15506
+ _log_finder_uin: "",
15507
+ _log_finder_id: finderId,
15508
+ rawKeyBuff: "",
15509
+ pluginSessionId: null,
15510
+ scene: 7,
15511
+ reqScene: 7
15512
+ }
15513
+ }, {
15514
+ retries: 3,
15515
+ retryDelay: 100,
15516
+ timeout: 5000
15517
+ });
15518
+ _task.logger.info(`视频号账号数据响应: ${JSON.stringify(authData)}`);
15519
+ const AUTH_ERROR_CODES = [
15520
+ 300333,
15521
+ 300334,
15522
+ 300330,
15523
+ 300331,
15524
+ 300332
15525
+ ];
15526
+ if (authData.errCode && AUTH_ERROR_CODES.includes(authData.errCode)) {
15527
+ _task.logger.warn(`视频号登录已失效:${authData.errMsg} (${authData.errCode})`);
15528
+ return types_errorResponse("视频号账号信息获取失败,请检查账号状态", 414);
15529
+ }
15530
+ if (authData.errCode) {
15531
+ _task.logger.warn(`视频号账号API错误:${authData.errMsg} (${authData.errCode})`);
15532
+ return types_errorResponse(`视频号账号信息获取失败:${authData.errMsg || "未知错误"}`, 414);
15533
+ }
15534
+ const finderUser = authData.data?.finderUser;
15535
+ const shipinhaoData = {
15536
+ fansNum: finderUser?.fansCount || 0,
15537
+ feedsCount: finderUser?.feedsCount || 0,
15538
+ fansNumYesterday: null,
15539
+ playNumYesterday: null,
15540
+ likeNumYesterday: null,
15541
+ commentNumYesterday: null
15542
+ };
15543
+ return (0, share_namespaceObject.success)(shipinhaoData, "视频号平台数据获取成功!");
15544
+ } catch (error) {
15545
+ if (error && "object" == typeof error && "code" in error && "message" in error) {
15546
+ const err = error;
15547
+ _task.logger.error(`视频号账号数据获取失败: ${err.message} (${err.code})`);
15548
+ return types_errorResponse(err.message, err.code);
15549
+ }
15550
+ const errMsg = error instanceof Error ? error.message : String(error);
15551
+ _task.logger.error(`视频号账号数据获取失败: ${errMsg}`);
15552
+ return types_errorResponse(errMsg || "视频号账号数据获取失败");
15553
+ }
15554
+ }
15362
15555
  async function getToutiaoData(_task, params) {
15363
15556
  const http = new Http({
15364
15557
  headers: {
@@ -15457,7 +15650,7 @@ var __webpack_exports__ = {};
15457
15650
  userInfoHtmlPromise,
15458
15651
  userSummaryHtmlPromise
15459
15652
  ]);
15460
- if (userInfoHtml.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return types_errorResponse("Token已失效,请重新获取", 414);
15653
+ if (userInfoHtml.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return types_errorResponse("微信公众号数据获取失败,请检查账号状态", 414);
15461
15654
  const userInfoJson = exportWxCgiData(userInfoHtml);
15462
15655
  const userSummaryJson = exportWxCgiData(userSummaryHtml);
15463
15656
  const wxData = {
@@ -15534,7 +15727,9 @@ var __webpack_exports__ = {};
15534
15727
  "toutiao",
15535
15728
  "xiaohongshu",
15536
15729
  "weixin",
15537
- "baijiahao"
15730
+ "baijiahao",
15731
+ "douyin",
15732
+ "shipinhao"
15538
15733
  ])
15539
15734
  });
15540
15735
  const SearchAccountInfo = async (_task, params)=>{
@@ -15548,6 +15743,10 @@ var __webpack_exports__ = {};
15548
15743
  return getWeixinData(_task, params);
15549
15744
  case "baijiahao":
15550
15745
  return getBaijiahaoData(_task, params);
15746
+ case "douyin":
15747
+ return getDouyinData(_task, params);
15748
+ case "shipinhao":
15749
+ return getShipinhaoData(_task, params);
15551
15750
  default:
15552
15751
  return (0, share_namespaceObject.success)(null, "暂不支持该平台");
15553
15752
  }
@@ -15811,21 +16010,6 @@ var __webpack_exports__ = {};
15811
16010
  params.accountId
15812
16011
  ];
15813
16012
  const http = new Http(...args);
15814
- let authorUid = "";
15815
- try {
15816
- const userInfo = await http.api({
15817
- method: "get",
15818
- url: "https://creator.douyin.com/aweme/v1/creator/user/info/"
15819
- }, {
15820
- retries: 3,
15821
- retryDelay: 100,
15822
- timeout: 5000
15823
- });
15824
- authorUid = userInfo.user_profile?.unique_id || "";
15825
- if (!userInfo.has_data_mgmt_perm) _task.logger.warn("抖音账号未开通数据中心权限,近7日数据不可用");
15826
- } catch (error) {
15827
- _task.logger.warn("获取抖音用户信息失败");
15828
- }
15829
16013
  async function fetchWorks(cursor) {
15830
16014
  return await http.api({
15831
16015
  method: "get",
@@ -15844,25 +16028,31 @@ var __webpack_exports__ = {};
15844
16028
  timeout: 5000
15845
16029
  });
15846
16030
  }
15847
- const firstPageCursor = (pageNum - 1) * pageSize;
15848
- const workListResponse = await fetchWorks(firstPageCursor);
15849
- if (!workListResponse || !workListResponse.aweme_list) return searchPublishInfo_types_errorResponse("抖音数据获取失败,请检查账号状态", 414);
16031
+ const isHasMore = (v)=>true === v || 1 === v;
16032
+ const skipCount = (pageNum - 1) * pageSize;
16033
+ const needCount = skipCount + pageSize;
16034
+ const workListResponse = await fetchWorks(0);
16035
+ if (!workListResponse || !Array.isArray(workListResponse.aweme_list)) return searchPublishInfo_types_errorResponse("抖音数据获取失败,请检查账号状态", 414);
15850
16036
  const allWorks = [
15851
16037
  ...workListResponse.aweme_list
15852
16038
  ];
15853
- let hasMore = workListResponse.has_more;
15854
- let currentCursor = workListResponse.max_cursor;
15855
- while(allWorks.length < pageSize && hasMore && !onlySuccess){
16039
+ let hasMore = isHasMore(workListResponse.has_more);
16040
+ let currentCursor = workListResponse.cursor ?? workListResponse.max_cursor ?? 0;
16041
+ let guard = 0;
16042
+ while(allWorks.length < needCount && hasMore && guard < 20){
15856
16043
  const nextPageResponse = await fetchWorks(currentCursor);
16044
+ if (!Array.isArray(nextPageResponse.aweme_list) || 0 === nextPageResponse.aweme_list.length) break;
15857
16045
  allWorks.push(...nextPageResponse.aweme_list);
15858
- hasMore = nextPageResponse.has_more;
15859
- currentCursor = nextPageResponse.max_cursor;
15860
- if (allWorks.length >= 2 * pageSize) break;
16046
+ hasMore = isHasMore(nextPageResponse.has_more);
16047
+ currentCursor = nextPageResponse.cursor ?? nextPageResponse.max_cursor ?? currentCursor;
16048
+ guard++;
15861
16049
  }
15862
- const finalWorks = allWorks.slice(0, pageSize);
16050
+ const finalWorks = allWorks.slice(skipCount, needCount);
15863
16051
  const articleCell = finalWorks.map((item)=>{
15864
16052
  const workDetailUrl = `https://creator.douyin.com/creator-micro/work-management/work-detail/${item.aweme_id}`;
15865
- const workPublicUrl = authorUid ? `https://www.douyin.com/user/${authorUid}?modal_id=${item.aweme_id}` : `https://www.douyin.com/video/${item.aweme_id}`;
16053
+ const workPublicUrl = item.share_url || `https://www.douyin.com/video/${item.aweme_id}`;
16054
+ let statusText;
16055
+ statusText = item.status?.is_delete ? "deleted" : item.status?.is_private ? "private" : item.status?.in_reviewing ? "reviewing" : "public";
15866
16056
  return {
15867
16057
  title: item.desc || "无作品描述",
15868
16058
  imageUrl: item.Cover?.url_list?.[0] || "",
@@ -15874,9 +16064,9 @@ var __webpack_exports__ = {};
15874
16064
  shareNum: item.statistics?.share_count || 0,
15875
16065
  collectNum: item.statistics?.collect_count || 0,
15876
16066
  awemeId: item.aweme_id,
15877
- awemeType: item.aweme_type,
16067
+ awemeType: item.aweme_type ?? 0,
15878
16068
  duration: item.duration,
15879
- status: item.status?.is_private ? "private" : item.status?.in_reviewing ? "reviewing" : "public",
16069
+ status: statusText,
15880
16070
  publicUrl: workPublicUrl,
15881
16071
  ...showOriginalData ? {
15882
16072
  originalData: item
@@ -15887,8 +16077,8 @@ var __webpack_exports__ = {};
15887
16077
  articleCell,
15888
16078
  ...onlySuccess ? {
15889
16079
  pagination: {
15890
- total: workListResponse.total || workListResponse.aweme_list.length,
15891
- nextPage: workListResponse.has_more,
16080
+ total: workListResponse.total || allWorks.length,
16081
+ nextPage: hasMore,
15892
16082
  pageNum,
15893
16083
  pageSize
15894
16084
  }
@@ -15984,14 +16174,21 @@ var __webpack_exports__ = {};
15984
16174
  const needArticle = "all" === postType || "article" === postType;
15985
16175
  const AUTH_ERROR_CODES = [
15986
16176
  300333,
15987
- 300334
16177
+ 300334,
16178
+ 300330,
16179
+ 300331,
16180
+ 300332
15988
16181
  ];
15989
16182
  if (needVideo) try {
15990
16183
  const videoPageUrl = "https://channels.weixin.qq.com/micro/content/post/list";
15991
16184
  const videoResponse = await fetchPosts(pageNum, 11, videoPageUrl);
16185
+ _task.logger.info(`视频号视频获取响应:${JSON.stringify(videoResponse)}`);
15992
16186
  if (videoResponse.errCode && AUTH_ERROR_CODES.includes(videoResponse.errCode)) throw new Error(`AUTH_ERROR:${videoResponse.errMsg || "登录已失效"}`);
15993
- if (videoResponse.errCode) _task.logger.warn(`视频号API错误:${videoResponse.errMsg} (${videoResponse.errCode})`);
15994
- else {
16187
+ if (videoResponse.errCode) {
16188
+ _task.logger.warn(`视频号API错误:${videoResponse.errMsg} (${videoResponse.errCode})`);
16189
+ throw new Error(`视频号API错误:${videoResponse.errMsg} (${videoResponse.errCode})`);
16190
+ }
16191
+ {
15995
16192
  const posts = videoResponse.data?.list || videoResponse.posts || videoResponse.post_list || [];
15996
16193
  const videoArticles = posts.filter((item)=>item.createTime || item.create_time).map((item)=>mapPost(item, "video"));
15997
16194
  allArticles.push(...videoArticles);
@@ -16006,8 +16203,11 @@ var __webpack_exports__ = {};
16006
16203
  const articlePageUrl = "https://channels.weixin.qq.com/micro/content/post/finderNewLifePostList";
16007
16204
  const articleResponse = await fetchPosts(pageNum, 10, articlePageUrl);
16008
16205
  if (articleResponse.errCode && AUTH_ERROR_CODES.includes(articleResponse.errCode)) throw new Error(`AUTH_ERROR:${articleResponse.errMsg || "登录已失效"}`);
16009
- if (articleResponse.errCode) _task.logger.warn(`视频号图文API错误:${articleResponse.errMsg} (${articleResponse.errCode})`);
16010
- else {
16206
+ if (articleResponse.errCode) {
16207
+ _task.logger.warn(`视频号图文API错误:${articleResponse.errMsg} (${articleResponse.errCode})`);
16208
+ throw new Error(`视频号图文API错误:${articleResponse.errMsg} (${articleResponse.errCode})`);
16209
+ }
16210
+ {
16011
16211
  const posts = articleResponse.data?.list || articleResponse.posts || articleResponse.post_list || [];
16012
16212
  const articleArticles = posts.filter((item)=>item.createTime || item.create_time).map((item)=>mapPost(item, "article"));
16013
16213
  allArticles.push(...articleArticles);
@@ -25058,6 +25258,24 @@ var __webpack_exports__ = {};
25058
25258
  likeNumYesterday: schemas_number().nullable(),
25059
25259
  commentNumYesterday: schemas_number().nullable()
25060
25260
  });
25261
+ schemas_object({
25262
+ fansNum: schemas_number(),
25263
+ favedNum: schemas_number(),
25264
+ fansNumLastWeek: schemas_number(),
25265
+ watchNumLastWeek: schemas_number(),
25266
+ likeNumLastWeek: schemas_number(),
25267
+ commentNumLastWeek: schemas_number(),
25268
+ shareNumLastWeek: schemas_number(),
25269
+ visitNumLastWeek: schemas_number()
25270
+ });
25271
+ schemas_object({
25272
+ fansNum: schemas_number(),
25273
+ feedsCount: schemas_number(),
25274
+ fansNumYesterday: schemas_number().nullable(),
25275
+ playNumYesterday: schemas_number().nullable(),
25276
+ likeNumYesterday: schemas_number().nullable(),
25277
+ commentNumYesterday: schemas_number().nullable()
25278
+ });
25061
25279
  const BetaFlag = "HuiwenCanary";
25062
25280
  class Action {
25063
25281
  constructor(task){