// # Source: https://github.com/imoki/sign_script/blob/main/polymerization/ddmc_ddyt.js // # Raw: https://raw.githubusercontent.com/imoki/sign_script/main/polymerization/ddmc_ddyt.js // # Repo: imoki/sign_script // # Path: polymerization/ddmc_ddyt.js // # UploadedAt: 2025-08-25T21:29:14+08:00 // # SHA256: 8848c2ac8c9c09a61d016a63d4ebba5937c435dca08666179c5a2be34ed1df8f // # Category: web版/账密 // # Evidence: web/H5关键词 + username/password/login // /* name: "叮咚鱼塘" cron: 45 0 9 * * * 脚本兼容: 金山文档(1.0),金山文档(2.0) 更新时间:20241025 环境变量名:无 环境变量值:无 备注:需要Cookie、seedId、propsId。 "叮咚买菜"APP,然后用抓包软件进行抓包,分别在叮咚鱼塘中点击喂饲料,在果园中点击浇水,就能抓到含有Cookie、seedId和propsId的包。 */ var sheetNameSubConfig = "ddmc"; // 分配置表名称 let sheetNameSubConfig2 = "ddmc_ddyt"; var pushHeader = "【叮咚鱼塘】"; var sheetNameConfig = "CONFIG"; // 总配置表 var sheetNamePush = "PUSH"; // 推送表名称 var sheetNameEmail = "EMAIL"; // 邮箱表 var flagSubConfig = 0; // 激活分配置工作表标志 var flagConfig = 0; // 激活主配置工作表标志 var flagPush = 0; // 激活推送工作表标志 var line = 21; // 指定读取从第2行到第line行的内容 var message = ""; // 待发送的消息 var messageArray = []; // 待发送的消息数据,每个元素都是某个账号的消息。目的是将不同用户消息分离,方便个性化消息配置 var messageOnlyError = 0; // 0为只推送失败消息,1则为推送成功消息。 var messageNickname = 0; // 1为推送位置标识(昵称/单元格Ax(昵称为空时)),0为不推送位置标识 var messageHeader = []; // 存放每个消息的头部,如:单元格A3。目的是分离附加消息和执行结果消息 var messagePushHeader = pushHeader; // 存放在总消息的头部,默认是pushHeader,如:【xxxx】 var version = 1 // 版本类型,自动识别并适配。默认为airscript 1.0,否则为2.0(Beta) var separator = "##########MOKU##########" // 分割符,分割消息。可用于PUSH.js灵活推送 var maxMessageLength = 400; // 设置最大长度,超过这个长度则分片发送 var messageDistance = 100; // 消息距离,用于匹配100字符内最近的行 var jsonPush = [ { name: "bark", key: "xxxxxx", flag: "0" }, { name: "pushplus", key: "xxxxxx", flag: "0" }, { name: "ServerChan", key: "xxxxxx", flag: "0" }, { name: "email", key: "xxxxxx", flag: "0" }, { name: "dingtalk", key: "xxxxxx", flag: "0" }, { name: "discord", key: "xxxxxx", flag: "0" }, ]; // 推送数据,flag=1则推送 var jsonEmail = { server: "", port: "", sender: "", authorizationCode: "", }; // 有效邮箱配置 // =================青龙适配开始=================== qlSwitch = 0 // =================青龙适配结束=================== // =================金山适配开始=================== // airscript检测版本 function checkVesion(){ try{ let temp = Application.Range("A1").Text; Application.Range("A1").Value = temp console.log("😶‍🌫️ 检测到当前airscript版本为1.0,进行1.0适配") }catch{ console.log("😶‍🌫️ 检测到当前airscript版本为2.0,进行2.0适配") version = 2 } } // 推送相关 // 获取时间 function getDate(){ let currentDate = new Date(); currentDate = currentDate.getFullYear() + '/' + (currentDate.getMonth() + 1).toString() + '/' + currentDate.getDate().toString(); return currentDate } // 将消息写入CONFIG表中作为消息队列,之后统一发送 function writeMessageQueue(message){ // 当天时间 let todayDate = getDate() flagConfig = ActivateSheet(sheetNameConfig); // 激活主配置表 // 主配置工作表存在 if (flagConfig == 1) { console.log("✨ 开始将结果写入主配置表"); for (let i = 2; i <= 100; i++) { // 找到指定的表行 if(Application.Range("A" + (i + 2)).Value == sheetNameSubConfig2){ // 写入更新的时间 Application.Range("F" + (i + 2)).Value = todayDate // 写入消息 Application.Range("G" + (i + 2)).Value = message console.log("✨ 写入结果完成"); break; } } } } // 总推送 function push(message) { writeMessageQueue(message) // 将消息写入CONFIG表中 // if (message != "") { // // message = messagePushHeader + message // 消息头最前方默认存放:【xxxx】 // let length = jsonPush.length; // let name; // let key; // for (let i = 0; i < length; i++) { // if (jsonPush[i].flag == 1) { // name = jsonPush[i].name; // key = jsonPush[i].key; // if (name == "bark") { // bark(message, key); // } else if (name == "pushplus") { // pushplus(message, key); // } else if (name == "ServerChan") { // serverchan(message, key); // } else if (name == "email") { // email(message); // } else if (name == "dingtalk") { // dingtalk(message, key); // } else if (name == "discord") { // discord(message, key); // } // } // } // } else { // console.log("🍳 消息为空不推送"); // } } // 推送bark消息 function bark(message, key) { if (key != "") { message = messagePushHeader + message // 消息头最前方默认存放:【xxxx】 message = encodeURIComponent(message) BARK_ICON = "https://s21.ax1x.com/2024/06/23/pkrUkfe.png" let url = "https://api.day.app/" + key + "/" + message + "/" + "?icon=" + BARK_ICON; // 若需要修改推送的分组,则将上面一行改为如下的形式 // let url = 'https://api.day.app/' + bark_id + "/" + message + "?group=分组名"; let resp = HTTP.get(url, { headers: { "Content-Type": "application/x-www-form-urlencoded" }, }); sleep(5000); } } // 推送pushplus消息 function pushplus(message, key) { if (key != "") { message = encodeURIComponent(message) // url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message; url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message + "&title=" + pushHeader; // 增加标题 let resp = HTTP.fetch(url, { method: "get", }); sleep(5000); } } // 推送serverchan消息 function serverchan(message, key) { if (key != "") { url = "https://sctapi.ftqq.com/" + key + ".send" + "?title=" + messagePushHeader + "&desp=" + message; let resp = HTTP.fetch(url, { method: "get", }); sleep(5000); } } // email邮箱推送 function email(message) { var myDate = new Date(); // 创建一个表示当前时间的 Date 对象 var data_time = myDate.toLocaleDateString(); // 获取当前日期的字符串表示 let server = jsonEmail.server; let port = parseInt(jsonEmail.port); // 转成整形 let sender = jsonEmail.sender; let authorizationCode = jsonEmail.authorizationCode; let mailer; mailer = SMTP.login({ host: server, port: port, username: sender, password: authorizationCode, secure: true, }); mailer.send({ from: pushHeader + "<" + sender + ">", to: sender, subject: pushHeader + " - " + data_time, text: message, }); // console.log("🍳 已发送邮件至:" + sender); console.log("🍳 已发送邮件"); sleep(5000); } // 邮箱配置 function emailConfig() { console.log("🍳 开始读取邮箱配置"); let length = jsonPush.length; // 因为此json数据可无序,因此需要遍历 let name; for (let i = 0; i < length; i++) { name = jsonPush[i].name; if (name == "email") { if (jsonPush[i].flag == 1) { let flag = ActivateSheet(sheetNameEmail); // 激活邮箱表 // 邮箱表存在 // var email = { // 'email':'', 'port':'', 'sender':'', 'authorizationCode':'' // } // 有效配置 if (flag == 1) { console.log("🍳 开始读取邮箱表"); for (let i = 2; i <= 2; i++) { // 从工作表中读取推送数据 jsonEmail.server = Application.Range("A" + i).Text; jsonEmail.port = Application.Range("B" + i).Text; jsonEmail.sender = Application.Range("C" + i).Text; jsonEmail.authorizationCode = Application.Range("D" + i).Text; if (Application.Range("A" + i).Text == "") { // 如果为空行,则提前结束读取 break; } } // console.log(jsonEmail) } break; } } } } // 推送钉钉机器人 function dingtalk(message, key) { message = messagePushHeader + message // 消息头最前方默认存放:【xxxx】 let url = "https://oapi.dingtalk.com/robot/send?access_token=" + key; let resp = HTTP.post(url, { msgtype: "text", text: { content: message } }); // console.log(resp.text()) sleep(5000); } // 推送Discord机器人 function discord(message, key) { message = messagePushHeader + message // 消息头最前方默认存放:【xxxx】 let url = key; let resp = HTTP.post(url, { content: message }); //console.log(resp.text()) sleep(5000); } // =================金山适配结束=================== // =================共用开始=================== // main() // 入口 // function main(){ checkVesion() // 版本检测,以进行不同版本的适配 flagConfig = ActivateSheet(sheetNameConfig); // 激活推送表 // 主配置工作表存在 if (flagConfig == 1) { console.log("🍳 开始读取主配置表"); let name; // 名称 let onlyError; let nickname; for (let i = 2; i <= 100; i++) { // 从工作表中读取推送数据 name = Application.Range("A" + i).Text; onlyError = Application.Range("C" + i).Text; nickname = Application.Range("D" + i).Text; if (name == "") { // 如果为空行,则提前结束读取 break; // 提前退出,提高效率 } if (name == sheetNameSubConfig) { if (onlyError == "是") { messageOnlyError = 1; console.log("🍳 只推送错误消息"); } if (nickname == "是") { messageNickname = 1; console.log("🍳 单元格用昵称替代"); } break; // 提前退出,提高效率 } } } flagPush = ActivateSheet(sheetNamePush); // 激活推送表 // 推送工作表存在 if (flagPush == 1) { console.log("🍳 开始读取推送工作表"); let pushName; // 推送类型 let pushKey; let pushFlag; // 是否推送标志 for (let i = 2; i <= line; i++) { // 从工作表中读取推送数据 pushName = Application.Range("A" + i).Text; pushKey = Application.Range("B" + i).Text; pushFlag = Application.Range("C" + i).Text; if (pushName == "") { // 如果为空行,则提前结束读取 break; } jsonPushHandle(pushName, pushFlag, pushKey); } // console.log(jsonPush) } // 邮箱配置函数 emailConfig(); flagSubConfig = ActivateSheet(sheetNameSubConfig); // 激活分配置表 if (flagSubConfig == 1) { console.log("🍳 开始读取分配置表"); if(qlSwitch != 1){ // 金山文档 for (let i = 2; i <= line; i++) { var cookie = Application.Range("A" + i).Text; var exec = Application.Range("B" + i).Text; if (cookie == "") { // 如果为空行,则提前结束读取 break; } if (exec == "是") { execHandle(cookie, i); } } message = messageMerge()// 将消息数组融合为一条总消息 push(message); // 推送消息 }else{ for (let i = 2; i <= line; i++) { var cookie = Application.Range("A" + i).Text; var exec = Application.Range("B" + i).Text; if (cookie == "") { // 如果为空行,则提前结束读取 break; } if (exec == "是") { console.log("🧑 开始执行用户:" + "1" ) execHandle(cookie, i); break; // 只取一个 } } } } // } // 激活工作表函数 function ActivateSheet(sheetName) { let flag = 0; try { // 激活工作表 let sheet = Application.Sheets.Item(sheetName); sheet.Activate(); console.log("🥚 激活工作表:" + sheet.Name); flag = 1; } catch { flag = 0; console.log("🍳 无法激活工作表,工作表可能不存在"); } return flag; } // 对推送数据进行处理 function jsonPushHandle(pushName, pushFlag, pushKey) { let length = jsonPush.length; for (let i = 0; i < length; i++) { if (jsonPush[i].name == pushName) { if (pushFlag == "是") { jsonPush[i].flag = 1; jsonPush[i].key = pushKey; } } } } // 将消息数组融合为一条总消息 function messageMerge(){ // console.log(messageArray) let message = "" for(i=0; i 0){ console.log("🍳 尝试完成任务...") for (let j = 0; j < taskCode.length; j++) { urlTask = url[5] + taskCode[j] // console.log(urlTask) try{ // resp = HTTP.fetch(urlTask, { // method: "get", // headers: headers, // }); resp = HTTP.get(urlTask, {headers: headers,}); // console.log(resp.text()) sleep(2000) }catch{ console.log("🍳 忽略任务:" + taskCode[j]) } } } // 获取奖励id // resp = HTTP.fetch(url[4], { // method: "get", // headers: headers, // }); resp = HTTP.get(url[4], {headers: headers,}); if (resp.status == 200) { resp = resp.json(); // console.log(resp); code = resp["code"]; if(code == 0){ console.log("🍳 正在获取userTaskLogId "); userTasks = resp["data"]["userTasks"]; let temp let num = 0 for (let j = 0; j < userTasks.length; j++) { temp = userTasks[j]["userTaskLogId"] // console.log(typeof(temp)) // console.log(temp.length) // 长度为18才是id if(typeof(temp) != "object"){ // || temp != "{}" || temp != "null" || temp != "" || temp != null userTaskLogId[num] = temp num += 1 } } console.log(userTaskLogId) }else{ console.log("🍳 获取userTaskLogId失败 "); } } else { console.log(resp.text()); console.log("🍳 获取userTaskLogId失败 "); } // 领取任务奖励 if(userTaskLogId.length > 0){ console.log("🍳 尝试领取任务奖励...") for (let j = 0; j < userTaskLogId.length; j++) { urlTask = url[6] + userTaskLogId[j] // console.log(urlTask) try{ // resp = HTTP.fetch(urlTask, { // method: "get", // headers: headers, // }); resp = HTTP.get(urlTask, {headers: headers,}); // console.log(resp.text()) sleep(2000) }catch{ console.log("🍳 忽略任务:" + userTaskLogId[j]) } } }else{ console.log("🍳 没有可领取的奖励") } // 喂饲料 let amount = 10; // 记录剩余数目 let amoutCount = 0; // 已喂饲料次数 let flagAmount = 0; // 标志,1为饲料 let countSeedId = 0; // 计算是不是每次浇花的剩余水量都一样,如果三次都一样,则认为seedid过期 let lastamount = 0; // 记录上一次剩余水量 while(amount >= 10){ // resp = HTTP.fetch(url[3], { // method: "get", // headers: headers, // }); resp = HTTP.get(url[3], {headers: headers,}); if (resp.status == 200) { resp = resp.json(); // console.log(resp); code = resp["code"]; msg = resp["msg"]; if(code == 0){ amount = resp["data"]["props"]["amount"]; // 用于判断seedId是否过期,也即浇水是否失败 if(lastamount == amount){ // 和上次剩余水量一样,可能没浇水成功 countSeedId += 1; // 记录相同次数 }else{ countSeedId = 0; // 水量不同,浇水成功,置零 } lastamount = amount; // 记录水量,以便下一次循环使用 if(countSeedId >=3){ // 浇了三次剩余水量都相同,则认为浇水失败,不再浇水,并提醒用户更换新的seedId值 msg = "[❗❗❗提醒]seedId值可能过期,请抓包获取最新的值" messageFail += "[❗❗❗提醒]seedId值可能过期,请抓包获取最新的值" console.log("🍳 提前退出浇水,错误消息为:" + msg) amoutCount -= 3; // 减去浇水失败的次数 break; } flagAmount = 1; amoutCount += 1; console.log("🍳 喂饲料中... ,剩余饲料:" + amount) }else{ console.log(resp); console.log("🍳 提前退出喂饲料,错误消息为:" + msg) amount = 0; // 直接置水为0 退出投喂 } } else { console.log(resp.text()); console.log("🍳 提前退出喂饲料") amount = 0; // 直接置水为0 退出投喂 } sleep(3000) } if(flagAmount == 1){ content = "🎉 " + "成功喂饲料" + amoutCount + "次\n" messageSuccess += content console.log(content); }else{ // messageFail += "喂饲料日志:" + msg + " "; // 此错误消息无需推送 console.log("📢 " + "喂饲料日志:" + msg + " "); } } catch { messageFail += "❌ " + messageName + "失败\n"; } sleep(2000); if (messageOnlyError == 1) { messageArray[posLabel] = messageFail; } else { if(messageFail != ""){ messageArray[posLabel] = messageFail + " " + messageSuccess; }else{ messageArray[posLabel] = messageSuccess; } } if(messageArray[posLabel] != "") { console.log(messageArray[posLabel]); } }