@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.mjs CHANGED
@@ -4350,7 +4350,7 @@ function __webpack_require__(moduleId) {
4350
4350
  return module;
4351
4351
  };
4352
4352
  })();
4353
- var package_namespaceObject = JSON.parse('{"i8":"4.0.4-beta.0"}');
4353
+ var package_namespaceObject = JSON.parse('{"i8":"4.0.4-beta.1"}');
4354
4354
  const PROXY_CREDENTIALS = [
4355
4355
  {
4356
4356
  ip: "47.110.131.129",
@@ -15284,6 +15284,199 @@ async function getBaijiahaoData(_task, params) {
15284
15284
  };
15285
15285
  return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(bjhData, "百家号平台数据获取成功!");
15286
15286
  }
15287
+ async function getDouyinData(_task, params) {
15288
+ try {
15289
+ const sessionidCookie = params.cookies.find((it)=>"sessionid" === it.name)?.value;
15290
+ if (!sessionidCookie) return types_errorResponse("抖音账号数据异常,请重新绑定账号后重试。", 414);
15291
+ const csrfToken = params.cookies.find((it)=>"passport_csrf_token" === it.name)?.value || "";
15292
+ const headers = {
15293
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
15294
+ referer: "https://creator.douyin.com/creator-micro/home",
15295
+ origin: "https://creator.douyin.com",
15296
+ "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",
15297
+ ...csrfToken ? {
15298
+ "x-secsdk-csrf-token": csrfToken
15299
+ } : {}
15300
+ };
15301
+ const args = [
15302
+ {
15303
+ headers
15304
+ },
15305
+ _task.logger,
15306
+ params.proxyLoc,
15307
+ params.localIP,
15308
+ params.accountId
15309
+ ];
15310
+ const http = new Http(...args);
15311
+ const toNum = (val)=>{
15312
+ if (null == val) return 0;
15313
+ const n = Number.parseInt(String(val).replace(/[+,]/g, ""), 10);
15314
+ return Number.isNaN(n) ? 0 : n;
15315
+ };
15316
+ const userProfileP = http.api({
15317
+ method: "get",
15318
+ url: "https://www.douyin.com/aweme/v1/web/user/profile/self/",
15319
+ params: {
15320
+ device_platform: "webapp",
15321
+ aid: "6383",
15322
+ channel: "channel_pc_web",
15323
+ pc_client_type: "1",
15324
+ version_code: "170400",
15325
+ version_name: "17.4.0",
15326
+ cookie_enabled: "true",
15327
+ platform: "PC"
15328
+ }
15329
+ }, {
15330
+ retries: 3,
15331
+ retryDelay: 100,
15332
+ timeout: 10000
15333
+ }).catch((e)=>{
15334
+ _task.logger.warn(`抖音用户信息获取失败: ${e instanceof Error ? e.message : String(e)}`);
15335
+ return null;
15336
+ });
15337
+ const overviewP = http.api({
15338
+ method: "get",
15339
+ url: "https://creator.douyin.com/aweme/janus/creator/data/overview/all/",
15340
+ params: {
15341
+ last_days_type: 1,
15342
+ aid: 2906,
15343
+ app_name: "aweme_creator_platform",
15344
+ device_platform: "web"
15345
+ }
15346
+ }, {
15347
+ retries: 3,
15348
+ retryDelay: 100,
15349
+ timeout: 5000
15350
+ }).catch((e)=>{
15351
+ _task.logger.warn(`抖音近7日数据获取失败(可能未开通数据中心或被风控): ${e instanceof Error ? e.message : String(e)}`);
15352
+ return null;
15353
+ });
15354
+ const [userProfile, overview] = await Promise.all([
15355
+ userProfileP,
15356
+ overviewP
15357
+ ]);
15358
+ _task.logger.info(`抖音用户信息响应: ${JSON.stringify(userProfile)}`);
15359
+ _task.logger.info(`抖音近7日数据响应: ${JSON.stringify(overview)}`);
15360
+ let fansNum = 0;
15361
+ let favedNum = 0;
15362
+ let followingNum = 0;
15363
+ if (userProfile?.status_code === 0 && userProfile.user) {
15364
+ const user = userProfile.user;
15365
+ fansNum = toNum(user.follower_count);
15366
+ followingNum = toNum(user.following_count);
15367
+ favedNum = toNum(user.total_favorited);
15368
+ _task.logger.info(`提取用户数据 - 昵称: ${user.nickname}, 粉丝: ${fansNum}, 关注: ${followingNum}, 获赞: ${favedNum}, 作品: ${user.aweme_count}`);
15369
+ } else _task.logger.warn(`用户信息接口返回异常: status_code=${userProfile?.status_code}, msg=${userProfile?.status_msg}`);
15370
+ const ov = overview?.data;
15371
+ const douyinData = {
15372
+ fansNum,
15373
+ favedNum,
15374
+ fansNumLastWeek: toNum(ov?.fans_incr?.current_count),
15375
+ watchNumLastWeek: toNum(ov?.play_count?.current_count),
15376
+ likeNumLastWeek: toNum(ov?.like_count?.current_count),
15377
+ commentNumLastWeek: toNum(ov?.comment_count?.current_count),
15378
+ shareNumLastWeek: toNum(ov?.share_count?.current_count),
15379
+ visitNumLastWeek: toNum(ov?.profile_visit?.current_count)
15380
+ };
15381
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(douyinData, "抖音平台数据获取成功!");
15382
+ } catch (error) {
15383
+ if (error && "object" == typeof error && "code" in error && "message" in error) {
15384
+ const err = error;
15385
+ _task.logger.error(`抖音账号数据获取失败: ${err.message} (${err.code})`);
15386
+ return types_errorResponse(err.message, err.code);
15387
+ }
15388
+ const errMsg = error instanceof Error ? error.message : String(error);
15389
+ _task.logger.error(`抖音账号数据获取失败: ${errMsg}`);
15390
+ return types_errorResponse(errMsg || "抖音账号数据获取失败");
15391
+ }
15392
+ }
15393
+ async function getShipinhaoData(_task, params) {
15394
+ try {
15395
+ const sessionidCookie = params.cookies.find((it)=>"sessionid" === it.name)?.value;
15396
+ if (!sessionidCookie) return types_errorResponse("视频号账号数据异常,请重新绑定账号后重试。", 414);
15397
+ const uinCookie = params.cookies.find((it)=>"uin" === it.name || "wxuin" === it.name)?.value || "0000000000";
15398
+ const deviceIdCookie = params.cookies.find((it)=>"device_id" === it.name || "finger_print_device_id" === it.name)?.value;
15399
+ const aid = params.cookies.find((it)=>"_aid" === it.name)?.value || "9d3e0e9f-b842-498d-a273-4285d58df264";
15400
+ const finderId = params.cookies.find((it)=>"_log_finder_id" === it.name || "finder_id" === it.name)?.value || "";
15401
+ const headers = {
15402
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
15403
+ referer: "https://channels.weixin.qq.com/platform",
15404
+ origin: "https://channels.weixin.qq.com",
15405
+ "content-type": "application/json",
15406
+ "X-WECHAT-UIN": uinCookie,
15407
+ ...deviceIdCookie ? {
15408
+ "finger-print-device-id": deviceIdCookie
15409
+ } : {}
15410
+ };
15411
+ const args = [
15412
+ {
15413
+ headers
15414
+ },
15415
+ _task.logger,
15416
+ params.proxyLoc,
15417
+ params.localIP,
15418
+ params.accountId
15419
+ ];
15420
+ const http = new Http(...args);
15421
+ const authData = await http.api({
15422
+ method: "post",
15423
+ url: "https://channels.weixin.qq.com/cgi-bin/mmfinderassistant-bin/auth/auth_data",
15424
+ params: {
15425
+ _aid: aid,
15426
+ _rid: `${Date.now().toString(16)}-${Math.random().toString(36).substring(2, 9)}`,
15427
+ _pageUrl: encodeURIComponent("https://channels.weixin.qq.com/platform")
15428
+ },
15429
+ data: {
15430
+ timestamp: Date.now().toString(),
15431
+ _log_finder_uin: "",
15432
+ _log_finder_id: finderId,
15433
+ rawKeyBuff: "",
15434
+ pluginSessionId: null,
15435
+ scene: 7,
15436
+ reqScene: 7
15437
+ }
15438
+ }, {
15439
+ retries: 3,
15440
+ retryDelay: 100,
15441
+ timeout: 5000
15442
+ });
15443
+ _task.logger.info(`视频号账号数据响应: ${JSON.stringify(authData)}`);
15444
+ const AUTH_ERROR_CODES = [
15445
+ 300333,
15446
+ 300334,
15447
+ 300330,
15448
+ 300331,
15449
+ 300332
15450
+ ];
15451
+ if (authData.errCode && AUTH_ERROR_CODES.includes(authData.errCode)) {
15452
+ _task.logger.warn(`视频号登录已失效:${authData.errMsg} (${authData.errCode})`);
15453
+ return types_errorResponse("视频号账号信息获取失败,请检查账号状态", 414);
15454
+ }
15455
+ if (authData.errCode) {
15456
+ _task.logger.warn(`视频号账号API错误:${authData.errMsg} (${authData.errCode})`);
15457
+ return types_errorResponse(`视频号账号信息获取失败:${authData.errMsg || "未知错误"}`, 414);
15458
+ }
15459
+ const finderUser = authData.data?.finderUser;
15460
+ const shipinhaoData = {
15461
+ fansNum: finderUser?.fansCount || 0,
15462
+ feedsCount: finderUser?.feedsCount || 0,
15463
+ fansNumYesterday: null,
15464
+ playNumYesterday: null,
15465
+ likeNumYesterday: null,
15466
+ commentNumYesterday: null
15467
+ };
15468
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(shipinhaoData, "视频号平台数据获取成功!");
15469
+ } catch (error) {
15470
+ if (error && "object" == typeof error && "code" in error && "message" in error) {
15471
+ const err = error;
15472
+ _task.logger.error(`视频号账号数据获取失败: ${err.message} (${err.code})`);
15473
+ return types_errorResponse(err.message, err.code);
15474
+ }
15475
+ const errMsg = error instanceof Error ? error.message : String(error);
15476
+ _task.logger.error(`视频号账号数据获取失败: ${errMsg}`);
15477
+ return types_errorResponse(errMsg || "视频号账号数据获取失败");
15478
+ }
15479
+ }
15287
15480
  async function getToutiaoData(_task, params) {
15288
15481
  const http = new Http({
15289
15482
  headers: {
@@ -15380,7 +15573,7 @@ async function getWeixinData(_task, params) {
15380
15573
  userInfoHtmlPromise,
15381
15574
  userSummaryHtmlPromise
15382
15575
  ]);
15383
- if (userInfoHtml.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return types_errorResponse("Token已失效,请重新获取", 414);
15576
+ if (userInfoHtml.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return types_errorResponse("微信公众号数据获取失败,请检查账号状态", 414);
15384
15577
  const userInfoJson = exportWxCgiData(userInfoHtml);
15385
15578
  const userSummaryJson = exportWxCgiData(userSummaryHtml);
15386
15579
  const wxData = {
@@ -15457,7 +15650,9 @@ const SearchAccountInfoParamsSchema = ActionCommonParamsSchema.extend({
15457
15650
  "toutiao",
15458
15651
  "xiaohongshu",
15459
15652
  "weixin",
15460
- "baijiahao"
15653
+ "baijiahao",
15654
+ "douyin",
15655
+ "shipinhao"
15461
15656
  ])
15462
15657
  });
15463
15658
  const SearchAccountInfo = async (_task, params)=>{
@@ -15471,6 +15666,10 @@ const SearchAccountInfo = async (_task, params)=>{
15471
15666
  return getWeixinData(_task, params);
15472
15667
  case "baijiahao":
15473
15668
  return getBaijiahaoData(_task, params);
15669
+ case "douyin":
15670
+ return getDouyinData(_task, params);
15671
+ case "shipinhao":
15672
+ return getShipinhaoData(_task, params);
15474
15673
  default:
15475
15674
  return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(null, "暂不支持该平台");
15476
15675
  }
@@ -15734,21 +15933,6 @@ async function handleDouyinData(_task, params) {
15734
15933
  params.accountId
15735
15934
  ];
15736
15935
  const http = new Http(...args);
15737
- let authorUid = "";
15738
- try {
15739
- const userInfo = await http.api({
15740
- method: "get",
15741
- url: "https://creator.douyin.com/aweme/v1/creator/user/info/"
15742
- }, {
15743
- retries: 3,
15744
- retryDelay: 100,
15745
- timeout: 5000
15746
- });
15747
- authorUid = userInfo.user_profile?.unique_id || "";
15748
- if (!userInfo.has_data_mgmt_perm) _task.logger.warn("抖音账号未开通数据中心权限,近7日数据不可用");
15749
- } catch (error) {
15750
- _task.logger.warn("获取抖音用户信息失败");
15751
- }
15752
15936
  async function fetchWorks(cursor) {
15753
15937
  return await http.api({
15754
15938
  method: "get",
@@ -15767,25 +15951,31 @@ async function handleDouyinData(_task, params) {
15767
15951
  timeout: 5000
15768
15952
  });
15769
15953
  }
15770
- const firstPageCursor = (pageNum - 1) * pageSize;
15771
- const workListResponse = await fetchWorks(firstPageCursor);
15772
- if (!workListResponse || !workListResponse.aweme_list) return searchPublishInfo_types_errorResponse("抖音数据获取失败,请检查账号状态", 414);
15954
+ const isHasMore = (v)=>true === v || 1 === v;
15955
+ const skipCount = (pageNum - 1) * pageSize;
15956
+ const needCount = skipCount + pageSize;
15957
+ const workListResponse = await fetchWorks(0);
15958
+ if (!workListResponse || !Array.isArray(workListResponse.aweme_list)) return searchPublishInfo_types_errorResponse("抖音数据获取失败,请检查账号状态", 414);
15773
15959
  const allWorks = [
15774
15960
  ...workListResponse.aweme_list
15775
15961
  ];
15776
- let hasMore = workListResponse.has_more;
15777
- let currentCursor = workListResponse.max_cursor;
15778
- while(allWorks.length < pageSize && hasMore && !onlySuccess){
15962
+ let hasMore = isHasMore(workListResponse.has_more);
15963
+ let currentCursor = workListResponse.cursor ?? workListResponse.max_cursor ?? 0;
15964
+ let guard = 0;
15965
+ while(allWorks.length < needCount && hasMore && guard < 20){
15779
15966
  const nextPageResponse = await fetchWorks(currentCursor);
15967
+ if (!Array.isArray(nextPageResponse.aweme_list) || 0 === nextPageResponse.aweme_list.length) break;
15780
15968
  allWorks.push(...nextPageResponse.aweme_list);
15781
- hasMore = nextPageResponse.has_more;
15782
- currentCursor = nextPageResponse.max_cursor;
15783
- if (allWorks.length >= 2 * pageSize) break;
15969
+ hasMore = isHasMore(nextPageResponse.has_more);
15970
+ currentCursor = nextPageResponse.cursor ?? nextPageResponse.max_cursor ?? currentCursor;
15971
+ guard++;
15784
15972
  }
15785
- const finalWorks = allWorks.slice(0, pageSize);
15973
+ const finalWorks = allWorks.slice(skipCount, needCount);
15786
15974
  const articleCell = finalWorks.map((item)=>{
15787
15975
  const workDetailUrl = `https://creator.douyin.com/creator-micro/work-management/work-detail/${item.aweme_id}`;
15788
- const workPublicUrl = authorUid ? `https://www.douyin.com/user/${authorUid}?modal_id=${item.aweme_id}` : `https://www.douyin.com/video/${item.aweme_id}`;
15976
+ const workPublicUrl = item.share_url || `https://www.douyin.com/video/${item.aweme_id}`;
15977
+ let statusText;
15978
+ statusText = item.status?.is_delete ? "deleted" : item.status?.is_private ? "private" : item.status?.in_reviewing ? "reviewing" : "public";
15789
15979
  return {
15790
15980
  title: item.desc || "无作品描述",
15791
15981
  imageUrl: item.Cover?.url_list?.[0] || "",
@@ -15797,9 +15987,9 @@ async function handleDouyinData(_task, params) {
15797
15987
  shareNum: item.statistics?.share_count || 0,
15798
15988
  collectNum: item.statistics?.collect_count || 0,
15799
15989
  awemeId: item.aweme_id,
15800
- awemeType: item.aweme_type,
15990
+ awemeType: item.aweme_type ?? 0,
15801
15991
  duration: item.duration,
15802
- status: item.status?.is_private ? "private" : item.status?.in_reviewing ? "reviewing" : "public",
15992
+ status: statusText,
15803
15993
  publicUrl: workPublicUrl,
15804
15994
  ...showOriginalData ? {
15805
15995
  originalData: item
@@ -15810,8 +16000,8 @@ async function handleDouyinData(_task, params) {
15810
16000
  articleCell,
15811
16001
  ...onlySuccess ? {
15812
16002
  pagination: {
15813
- total: workListResponse.total || workListResponse.aweme_list.length,
15814
- nextPage: workListResponse.has_more,
16003
+ total: workListResponse.total || allWorks.length,
16004
+ nextPage: hasMore,
15815
16005
  pageNum,
15816
16006
  pageSize
15817
16007
  }
@@ -15907,14 +16097,21 @@ async function handleShipinhaoData(_task, params) {
15907
16097
  const needArticle = "all" === postType || "article" === postType;
15908
16098
  const AUTH_ERROR_CODES = [
15909
16099
  300333,
15910
- 300334
16100
+ 300334,
16101
+ 300330,
16102
+ 300331,
16103
+ 300332
15911
16104
  ];
15912
16105
  if (needVideo) try {
15913
16106
  const videoPageUrl = "https://channels.weixin.qq.com/micro/content/post/list";
15914
16107
  const videoResponse = await fetchPosts(pageNum, 11, videoPageUrl);
16108
+ _task.logger.info(`视频号视频获取响应:${JSON.stringify(videoResponse)}`);
15915
16109
  if (videoResponse.errCode && AUTH_ERROR_CODES.includes(videoResponse.errCode)) throw new Error(`AUTH_ERROR:${videoResponse.errMsg || "登录已失效"}`);
15916
- if (videoResponse.errCode) _task.logger.warn(`视频号API错误:${videoResponse.errMsg} (${videoResponse.errCode})`);
15917
- else {
16110
+ if (videoResponse.errCode) {
16111
+ _task.logger.warn(`视频号API错误:${videoResponse.errMsg} (${videoResponse.errCode})`);
16112
+ throw new Error(`视频号API错误:${videoResponse.errMsg} (${videoResponse.errCode})`);
16113
+ }
16114
+ {
15918
16115
  const posts = videoResponse.data?.list || videoResponse.posts || videoResponse.post_list || [];
15919
16116
  const videoArticles = posts.filter((item)=>item.createTime || item.create_time).map((item)=>mapPost(item, "video"));
15920
16117
  allArticles.push(...videoArticles);
@@ -15929,8 +16126,11 @@ async function handleShipinhaoData(_task, params) {
15929
16126
  const articlePageUrl = "https://channels.weixin.qq.com/micro/content/post/finderNewLifePostList";
15930
16127
  const articleResponse = await fetchPosts(pageNum, 10, articlePageUrl);
15931
16128
  if (articleResponse.errCode && AUTH_ERROR_CODES.includes(articleResponse.errCode)) throw new Error(`AUTH_ERROR:${articleResponse.errMsg || "登录已失效"}`);
15932
- if (articleResponse.errCode) _task.logger.warn(`视频号图文API错误:${articleResponse.errMsg} (${articleResponse.errCode})`);
15933
- else {
16129
+ if (articleResponse.errCode) {
16130
+ _task.logger.warn(`视频号图文API错误:${articleResponse.errMsg} (${articleResponse.errCode})`);
16131
+ throw new Error(`视频号图文API错误:${articleResponse.errMsg} (${articleResponse.errCode})`);
16132
+ }
16133
+ {
15934
16134
  const posts = articleResponse.data?.list || articleResponse.posts || articleResponse.post_list || [];
15935
16135
  const articleArticles = posts.filter((item)=>item.createTime || item.create_time).map((item)=>mapPost(item, "article"));
15936
16136
  allArticles.push(...articleArticles);
@@ -24979,6 +25179,24 @@ const bjhConfigDataSchema = schemas_object({
24979
25179
  likeNumYesterday: schemas_number().nullable(),
24980
25180
  commentNumYesterday: schemas_number().nullable()
24981
25181
  });
25182
+ schemas_object({
25183
+ fansNum: schemas_number(),
25184
+ favedNum: schemas_number(),
25185
+ fansNumLastWeek: schemas_number(),
25186
+ watchNumLastWeek: schemas_number(),
25187
+ likeNumLastWeek: schemas_number(),
25188
+ commentNumLastWeek: schemas_number(),
25189
+ shareNumLastWeek: schemas_number(),
25190
+ visitNumLastWeek: schemas_number()
25191
+ });
25192
+ schemas_object({
25193
+ fansNum: schemas_number(),
25194
+ feedsCount: schemas_number(),
25195
+ fansNumYesterday: schemas_number().nullable(),
25196
+ playNumYesterday: schemas_number().nullable(),
25197
+ likeNumYesterday: schemas_number().nullable(),
25198
+ commentNumYesterday: schemas_number().nullable()
25199
+ });
24982
25200
  const BetaFlag = "HuiwenCanary";
24983
25201
  class Action {
24984
25202
  constructor(task){