使用步骤

  1. 建议使用 Chrome 最新版。

  2. 浏览器的 User-Agent 必须包含 jdapp,如果是 Chrome 浏览器,可以按 F12 在开发者工具中的 Network Conditions 中进行修改。

提供一个UA

jdapp;android;8.3.0;9;865883042627193-60ab67f195fe;network/4g;model/MI 9 Transparent Edition;appBuild/69903;Mozilla/5.0 (Linux; Android 9.0; MI 9 Transparent Edition Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044330 Mobile Safari/537.36


打开 Network Conditions

打开 Network Conditions



修改 UA

修改 UA


  1. 之后点击 Sources 选项卡,并点击下方左边的 Snippets 选项卡(如果没有,请点击两个向右的箭头)。然后再点击 New snippet 创建一个脚本,之后把 main.js (文章最下面)里的内容统统粘贴进去即可。


运行步骤 1

运行步骤 1


  1. 访问 京东移动端网页,点击底部导航栏的【我的】,登录京东账号。

  2. 登录完成后,再右键点击脚本运行。如果任务全部完成,Console 会提示,所以请耐心等待。


运行步骤 2

运行步骤 2


  1. 任务执行完成后,就可以到京东 APP 见证奇迹的时刻。


运行结果

运行结果


脚本代码

var secretp = "";
var taskList = [];

// 恢复被覆盖的 alert 函数
(() => {
  var frame = document.createElement("iframe");
  frame.style.display = "none";
  document.body.appendChild(frame);
  window.alert = frame.contentWindow.alert;
})();

// 请求函数
var request = (functionId, body = {}) =>
  fetch("https://api.m.jd.com/client.action", {
    body: `functionId=${functionId}&body=${JSON.stringify(
      body
    )}&client=wh5&clientVersion=1.0.0`,
    headers: {
      "content-type": "application/x-www-form-urlencoded",
    },
    method: "POST",
    credentials: "include",
  });

// 模拟任务完成请求
var collector = (task, actionType) => {
  console.log(actionType ? "@领取任务:" : "@执行任务:", task);

  request("cakebaker_ckCollectScore", {
    taskId: task.taskId,
    itemId: task.itemId,
    actionType: actionType ? 1 : undefined,
    safeStr: JSON.stringify({ secretp }),
  })
    .then((res) => res.json())
    .then((res) => {
      console.log("调用结果:", res.data);

      // 如果是执行任务,即任务已经完成,则进行下一个任务
      if (!actionType) {
        start();
      }
    });
};

// 甄选优品任务处理
var superiorTask = (() => {
  // 是否有请求正在执行
  var isBusy = false;

  return (rawTaskCollection) => {
    var getFeedDetail = (copiedTaskCollection) => {
      request("cakebaker_getFeedDetail", {
        taskIds: copiedTaskCollection["productInfoVos"]
          .map((item) => item.itemId)
          .toString(),
      })
        .then((res) => res.json())
        .then((res) => {
          var result = res.data.result;

          // 确认任务集合所在键名
          var taskCollectionContentKeyName = Object.keys(result).find(
            (keyName) => /Vos?$/.test(keyName) && !["taskVos"].includes(keyName)
          );

          result[taskCollectionContentKeyName].forEach((taskCollection) => {
            Array(taskCollection.maxTimes - taskCollection.times)
              .fill(true)
              .forEach((_, index) => {
                taskList.unshift({
                  taskName: taskCollection.taskName,
                  taskId: taskCollection.taskId,
                  taskType: taskCollection.taskType,
                  waitDuration: taskCollection.waitDuration,
                  itemId: taskCollection.productInfoVos[index].itemId,
                });
              });
          });

          // 解除请求锁定
          isBusy = false;
        });
    };

    if (!isBusy) {
      isBusy = true;
      getFeedDetail(JSON.parse(JSON.stringify(rawTaskCollection)));
    } else {
      // 一秒后重试
      setTimeout(
        getFeedDetail,
        1000,
        JSON.parse(JSON.stringify(rawTaskCollection))
      );
    }
  };
})();

// 开始任务
var start = () => {
  var task = taskList.pop();

  if (task) {
    // 除了小精灵和连签外的任务要先领取
    if (!["小精灵", "连签得金币"].includes(task.taskName)) {
      setTimeout(collector, 0, task, true);
    }
    // 至少等 2 秒再执行任务
    setTimeout(collector, (2 + task.waitDuration) * 1000, task);
  } else {
    console.log("@任务已完成!");
    alert("任务完成!");
  }
};

(() => {
  // 获取基础信息
  Promise.all([
    request("cakebaker_getHomeData"),
    // 请求稍微慢点,避免提示【点太快啦!等下再来吧】
    new Promise((resolve) => {
      setTimeout(() => {
        request("cakebaker_getTaskDetail").then(resolve);
      }, 1000);
    }),
  ])
    .then(([homeData, taskData]) =>
      Promise.all([homeData.json(), taskData.json()])
    )
    .then(([homeData, taskData]) => {
      // 如果无法获取任务详情
      if (taskData.data.bizCode !== 0) {
        if (
          taskData.data.bizCode === -7 &&
          !~navigator.userAgent.indexOf("jdapp")
        ) {
          console.log("当前浏览器 UA:" + navigator.userAgent);
          throw "任务详情获取失败,请确保已设置正确的浏览器 User-Agent。";
        } else {
          throw `【错误信息:${JSON.stringify(taskData.data)}】`;
        }
      }

      // 获取签名 token
      secretp = homeData.data.result.cakeBakerInfo.secretp;

      // 生成任务队列
      taskData.data.result.taskVos.forEach(async (taskCollection) => {
        // 跳过部分邀请任务
        if (
          ["邀请好友助力", "所在战队成员满5人"].includes(
            taskCollection.taskName
          )
        )
          return;

        // 针对甄选优品任务的处理
        if (taskCollection["productInfoVos"]) {
          superiorTask(taskCollection);
        }

        // 确认任务集合所在键名
        var taskCollectionContentKeyName = Object.keys(taskCollection).find(
          (keyName) =>
            /Vos?$/.test(keyName) &&
            !["productInfoVos", "scoreRuleVos"].includes(keyName)
        );

        // 某类任务下的任务集合内容
        taskCollectionContent = taskCollection[taskCollectionContentKeyName];

        if (!taskCollectionContent) return;

        Array(taskCollection.maxTimes - taskCollection.times)
          .fill(true)
          .forEach((_, index) => {
            taskList.push({
              taskName: taskCollection.taskName,
              taskId: taskCollection.taskId,
              taskType: taskCollection.taskType,
              waitDuration: taskCollection.waitDuration,
              itemId:
                taskCollectionContent instanceof Array
                  ? taskCollectionContent[index].itemId
                  : taskCollectionContent.itemId,
            });
          });
      });

      console.log(taskList);

      // 开始任务
      start();
    });
})();

注意事项

  1. 有网友提示每次调用后任务可能会不一样,建议脚本多跑一两次,一般三次就能跑完全部任务。

开源地址:https://github.com/zarkin404/sweater

欢迎留言

12 条评论

  1. 不好用了,第133行代码.bizCode 出错,报Uncaught (in promise) TypeError: Cannot read property 'bizCode' of undefined,,,,而且执行完任务也完不成。所以重新更新下吧!

    Windows 10 x64 Google Chrome 69.0.3497.100
  2. 虽然已经失效了,但是也学习了

    Windows 7 x64 Google Chrome 78.0.3904.108
  3. 不错,虽然活动结束了,但是也学习到了

    Windows 7 x64 Google Chrome 78.0.3904.108
  4. 活动太火爆,稍后再试,都是false。。

    Windows 10 x64 Google Chrome 78.0.3904.116
  5. 不好用了吧,,一运行,活动太火爆,稍后再试

    Windows 10 x64 Google Chrome 83.0.4103.97
  6. 老哥,京东的脚本今天不管用了呢

    Windows 10 x64 Google Chrome 81.0.4044.138
  7. 哥哥 你用淘宝的吗  来个淘宝的呗

    Windows 7 x64 Google Chrome 81.0.4044.138