2021-10-26 19:20:52 +08:00
/*
* 由ZCY01二次修改:脚本默认不运行
* 由 X1a0He 修复:依然保持脚本默认不运行
* 如需运行请自行添加环境变量:JD_TRY,值填 true 即可运行
* TG交流群:https://t.me/jd_zero205
* TG通知频道:https://t.me/jd_zero205_tz
*
update 2021/09/05
京东试用:脚本更新地址 https://github.com/zero205/JD_tencent_scf/raw/main/jd_try.js
脚本兼容: Node.js
每天最多关注300个商店,但用户商店关注上限为500个。
请配合取关脚本试用,使用 jd_unsubscribe.js 提前取关至少250个商店确保京东试用脚本正常运行。
*
* X1a0He留
* 由于没有兼容Qx,原脚本已失效,建议原脚本的兼容Qx注释删了
* 脚本是否耗时只看args_xh.maxLength的大小
* 上一作者说了每天最多300个商店,总上限为500个,jd_unsubscribe.js我已更新为批量取关版
* 请提前取关至少250个商店确保京东试用脚本正常运行
* 没有写通知,是否申请成功没有进行通知,但脚本会把状态log出日志
*/
let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0"
let dingtalk1 = "https://oapi.dingtalk.com/robot/send?access_token=a3e80da6f064321881fc38e43a07bfde7a61b6f18245454520fb749556cebfcd"
let totalPages = 999999 //总页数
const $ = new Env ( '京东试用' )
const URL = 'https://api.m.jd.com/client.action'
let trialActivityIdList = [ ]
let sensMessage = "试用\n\n"
let trialActivityTitleList = [ ]
let notifyMsg = ''
let message = ""
let minItemValue = 500
let wordLength = 1000
let process = {
env : {
"JD_TRY" : "true"
}
}
// default params
let args _xh = {
channelEnd : Math . floor ( Math . random ( ) * ( 4 ) + 3 ) ,
channel : [ 1 , 2 , 3 , 4 , 5 , 10 , 12 , 15 ] ,
maxSize : 15 ,
listCount : 0 ,
/*
* 是否进行通知
* 可设置环境变量:JD_TRY_NOTIFY
* */
// isNotify: process.env.JD_TRY_NOTIFY || true,
// 商品原价,低于这个价格都不会试用
2021-10-28 11:03:33 +08:00
jdPrice : 15 ,
2021-10-26 19:20:52 +08:00
/*
* 获取试用商品类型,默认为1
* 1 - 精选
* 2 - 闪电试用
* 3 - 家用电器(可能会有变化)
* 4 - 手机数码(可能会有变化)
* 5 - 电脑办公(可能会有变化)
* 可设置环境变量:JD_TRY_TABID
* */
// TODO: tab ids as array(support multi tabIds)
// tabId: process.env.JD_TRY_TABID && process.env.JD_TRY_TABID.split('@').map(Number) || [1],
tabId : process . env . JD _TRY _TABID || 1 ,
/*
* 试用商品标题过滤
* 可设置环境变量:JD_TRY_TITLEFILTERS,关键词与关键词之间用@分隔
* */
2021-10-28 11:03:33 +08:00
titleFilters : [ "刷子" , "菊粉" , "牙刷" , "冷凝胶" , "黑沙" , "秋梨膏" , "降葵花盘" , "台灯" , "儿童医生" , "过家家" , "面罩" , "摄影灯" , "补光灯" , "手电筒" , "手工DIY" , "棒棒糖" , "分线盒" , "变身器" , "魔法棒" , "购物袋" , "艾胜者" , "电源线" , "HEISHA" , "打虫糖" , "宝塔糖" , "消毒" , "口香糖" , "冰箱贴" , "气压杆" , "弹簧" , "摄像头" , "办公宝" , "球拍" , "羽毛球" , "脱毛" , "老式鸣笛" , "墨镜" , "排气扇" , "腰椎突出" , "FMJ" , "真空袋" , "公主项链" , "桌垫" , "沐浴包" , "孔明锁" , "碟子" , "防裂膏" , "干裂" , "塔菲克" , "托盘" , "番茄丁" , "反弹器" , "柜吸" , "门吸" , "自弹器" , "SMOVES" , "MS116" , "陀螺" , "门档" , "地吸" , "地桩" , "玻璃" , "清洁球" , "钢丝球" , "消毒液" , "泡澡球" , "隔音耳塞" , "翻分器" , "眼罩" , "乒乓球" , "布袋" , "枕头套" , "仓鼠零食" , "胸包" , "书包" , "周岁" , "抓周" , "干眼症" , "密码锁" , "防滑垫" , "椅背置物袋" , "艾脐贴" , "车内清洁" , "清洁刷" , "香薰" , "防疫" , "密封袋" , "早教" , "保鲜膜" , "底座" , "万向滑轮" , "高升专" , "专升本" , "学历" , "床头台灯" , "收敛水" , "鸡毛掸子" , "中国结" , "匙扣" , "糖糖粉" , "灭蝇" , "苍蝇药" , "苍蝇拍" , "假发" , "补发" , "陶瓷瓶" , "冷兵器" , "汽车椅背" , "擦玻璃" , "垃圾袋" , "擦窗" , "平光镜" , "眼镜" , "气垫霜" , "球帽" , "食盐" , "彩铅" , "手动幕" , "玻珠幕" , "玻珠" , "电脑电源" , "切菜板" , "隔热棉" , "过滤棉" , "园艺工具" , "砍菜刀" , "枇杷秋梨膏" , "唑溶液" , "滑块袋" , "育苗盘" , "隔热板" , "碟子" , "酵素" , "儿童吸管" , "体温计" , "茗杯" , "砂锅" , "呼噜" , "湿粮" , "膝盖贴" , "面酱" , "切菜板" , "油罐" , "油壶" , "茶具" , "茶宠" , "眼药水" , "体温计" , "儿童乐园" , "热敷包" , "茶壶" , "保温棉" , "双面板" , "消防水带" , "摄像头" , "除菌洗地液" , "地面清洁液" , "清洁配件" , "洗地专用" , "鱼缸" , "鱼竿" , "挂篓" , "茶壶" , "沉香" , "盘香" , "启动电源" , "摆件车模" , "摄像头" , "咖啡豆" , "投屏器" , "声卡套装" , "靠背收纳袋" , "切菜板" , "趴趴枕" , "洗地液" , "刹车油" , "提示牌" , "告知牌" , "警示牌" , "静音阻尼" , "信纸" , "信封" , "PVC板" , "标识牌" , "标志牌" , "锯条" , "摇步器" , "圣杯" , "撑衣杆" , "梳子" , "马桶刷" , "鱼缸" , "刨木" , "改光膜" , "手推车" , "电钻" , "行车记录仪" , "垃圾处理器" , "拉柳枪" , "花洒" , "自拍杆" , "百日宴" , "存储卡" , "艾绒贴" , "艾灸贴" , "清洁软胶" , "保护镜" , "uv镜" , "枇杷雪梨膏" , "枇杷膏" , "皮套" , "保护壳" , "徽墨" , "SUP掌机" , "台账本" , "墨条" , "墨块" , "去毛器" , "高清配件" , "拾音器" , "麦克风" , "类纸膜" , "坐骨膏" , "神经痛贴" , "专用贴" , "鸳鸯锅" , "4/3膜" , "镜头贴" , "后膜" , "摄像头膜" , "镜头膜" , "去角质" , "死皮" , "U盘" , "接线式直管" , "香囊袋" , "防疫香包" , "炖盅" , "如意碗" , "汽车头枕腰靠套装" , "湿手器" , "汤盅" , "面碗" , "风水鱼" , "打印机碳带" , "标签纸" , "不干胶标签带" , "清洁液" , "提词器" , "卡针" , "儿童电话手表" , "绷带" , "短裙" , "护具" , "卡册" , "黄金卡" , "贴布" , "护腕" , "鼠标手" , "儿童牙膏" , "锁头" , "闹钟" , "储奶袋" , "母乳" , "儿童电动牙刷" , "涂鸦贴纸" , "贴纸" , "抚奶嘴" , "牙套" , "戒奶嘴" , "断奶" , "饭盒" , "水凝膜" , "覆盖膜" , "背膜" , "百褶" , "半身裙" , "牙膏" , "风湿贴" , "刺激贴" , "冷敷贴" , "腰肌劳损" , "键盘垫" , "扭扭车" , "孩儿乐" , "儿童沐浴露" , "眼线笔" , "贴膜" , "笔" , "屏幕膜" , "修正带" , "封口机" , "对接头" , "网线" , "少儿读物" , "遮瑕" , "惯性小汽车" , "皮筋枪" , "身体乳" , "救生衣" , "裤" , "鞋" , "三轮车" , "起雾棒" , "干洗剂" , "白酒" , "口罩" , "碳粉" , "私处" , "创可贴" , "脖套" , "牵引器" , "木糖醇" , "富贵包" , "延长器" , "网卡" , "泡泡纸" , "戒烟" , "喷壶" , "刷头" , "面霜" , "宝宝霜" , "黑头" , "眼袋" , "防晒霜" , "护手霜" , "精华露" , "鼻头" , "细纹霜" , "抬头纹" , "美肌霜" , "素颜霜" , "儿童保温水杯" , "滋养霜" , "帽子" , "护膝" , "领带" , "露指" , "飞机杯" , "打飞机" , "保护膜" , "大头围" , "儿童随身" , "马丁靴" , "爸爸鞋" , "理发推" , "理发器" , "刀头" , "幕布" , "挡风玻璃" , "挡风板" , "乳液" , "测电笔" ,
2021-10-26 19:20:52 +08:00
// 试用价格(中了要花多少钱),高于这个价格都不会试用,小于等于才会试用
trialPrice : 0 ,
/*
* 最小提供数量,例如试用商品只提供2份试用资格,当前设置为1,则会进行申请
* 若只提供5分试用资格,当前设置为10,则不会申请
* 可设置环境变量:JD_TRY_MINSUPPLYNUM
* */
minSupplyNum : 20 ,
/*
* 过滤大于设定值的已申请人数,例如下面设置的1000,A商品已经有1001人申请了,则A商品不会进行申请,会被跳过
* 可设置环境变量:JD_TRY_APPLYNUMFILTER
* */
applyNumFilter : process . env . JD _TRY _APPLYNUMFILTER || 99999 ,
/*
* 商品试用之间和获取商品之间的间隔, 单位:毫秒(1秒=1000毫秒)
* 可设置环境变量:JD_TRY_APPLYINTERVAL
* */
applyInterval : process . env . JD _TRY _APPLYINTERVAL || 5000 ,
/*
* 商品数组的最大长度,通俗来说就是即将申请的商品队列长度
* 例如设置为20,当第一次获取后获得12件,过滤后剩下5件,将会进行第二次获取,过滤后加上第一次剩余件数
* 例如是18件,将会进行第三次获取,直到过滤完毕后为20件才会停止,不建议设置太大
* 可设置环境变量:JD_TRY_MAXLENGTH
* */
maxLength : 10
}
! ( async ( ) => {
// console.log(`\n本脚本默认不运行,也不建议运行\n如需运行请自行添加环境变量:JD_TRY,值填:true\n`)
await $ . wait ( 1000 )
if ( process . env . JD _TRY && process . env . JD _TRY === 'true' ) {
await requireConfig ( )
if ( ! $ . cookiesArr [ 0 ] ) {
$ . msg ( $ . name , '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取' , 'https://bean.m.jd.com/' , {
"open-url" : "https://bean.m.jd.com/"
} )
return
}
for ( let i = 0 ; i < $ . cookiesArr . length ; i ++ ) {
message += "<font color=\'#FFA500\'>[通知] </font><font color=\'#006400\' size='3'>随机试用</font> \n\n --- \n\n"
await $ . wait ( Math . floor ( Math . random ( ) * ( 10000 ) + 5000 ) ) ;
if ( $ . cookiesArr [ i ] ) {
$ . cookie = $ . cookiesArr [ i ] ;
$ . UserName = decodeURIComponent ( $ . cookie . match ( /pt_pin=(.+?);/ ) && $ . cookie . match ( /pt_pin=(.+?);/ ) [ 1 ] )
$ . index = i + 1 ;
$ . isLogin = true ;
$ . nickName = '' ;
await totalBean ( ) ;
console . log ( ` \n 开始【京东账号 ${ $ . index } 】 ${ $ . nickName || $ . UserName } \n ` ) ;
if ( ! $ . isLogin ) {
$ . msg ( $ . name , ` 【提示】cookie已失效 ` , ` 京东账号 ${ $ . index } ${ $ . nickName || $ . UserName } \n 请重新登录获取 \n https://bean.m.jd.com/bean/signIndex.action ` , {
"open-url" : "https://bean.m.jd.com/bean/signIndex.action"
} ) ;
await $ . notify . sendNotify ( ` ${ $ . name } cookie已失效 - ${ $ . UserName } ` , ` 京东账号 ${ $ . index } ${ $ . UserName } \n 请重新登录获取cookie ` ) ;
continue
}
username = $ . UserName
if ( $ . UserName == "jd_4521b375ebb5d" ) {
username = "锟子"
}
if ( $ . UserName == "jd_542c10c0222bc" ) {
username = "康子"
}
if ( $ . UserName == "jd_66dcb31363ef6" ) {
username = "涛子"
}
if ( $ . UserName == "18070420956_p" ) {
username = "奇怪子"
}
if ( $ . UserName == "jd_45d917547c763" ) {
username = "跑腿小弟子"
}
if ( $ . UserName == "jd_66ea783827d30" ) {
username = "军子"
}
if ( $ . UserName == "jd_4311ac0ff4456" ) {
username = "居子"
}
args _xh . maxLength = Math . floor ( Math . random ( ) * ( 20 ) + 10 )
let list = getList ( )
//加上名称
message = message + "<font color=\'#778899\' size=2>【羊毛姐妹】<font color=\'#FFA500\' size=3>" + username + " </font> </font> \n\n "
message = message + "<font color=\'#778899\' size=2>" + "数量大小:" + args _xh . maxLength + "申请列表:" + list + "</font> </font> \n\n "
$ . totalTry = 0
$ . totalSuccess = 0
let size = 1 ;
m = i
for ( let i = 0 ; i < list . length ; i ++ ) {
args _xh . maxSize = Math . floor ( Math . random ( ) * ( 30 ) + 10 )
message = message + "<font color=\'#FF0000\' size=2>" + "最大列表长度:" + args _xh . maxSize + " 申请列表:" + list [ i ] + "</font> </font> \n\n"
while ( args _xh . listCount + trialActivityIdList . length < args _xh . maxLength && size < args _xh . maxSize && size < totalPages - 1 ) {
console . log ( ` \n 正在进行第 ${ size } 次获取试用商品 \n ` )
console . log ( ` \n 当前产品页面总长度为 ${ totalPages } 页 \n ` )
await try _feedsList ( list [ i ] , size ++ )
if ( m == 0 && sensMessage . length > wordLength ) {
console . log ( "-----------------------------------" )
console . log ( "-----------------------------------" )
console . log ( "-----------------------------------" )
console . log ( "-----------------------------------" )
console . log ( "-----------------------------------" )
console . log ( "-----------------------------------" )
console . log ( "-----------------------------------" )
postToDingTalk1 ( sensMessage )
sensMessage = "试用\n\n"
} else {
console . log ( "------------清空------------" )
console . log ( "------------清空------------" )
sensMessage = "试用\n\n"
}
if ( args _xh . listCount + trialActivityIdList . length < args _xh . maxLength ) {
args _xh . applyInterval = Math . floor ( Math . random ( ) * ( 4000 ) + 5000 )
console . log ( ` 间隔延时中,请等待 ${ args _xh . applyInterval } ms ` )
await $ . wait ( args _xh . applyInterval ) ;
}
}
args _xh . listCount += trialActivityIdList . length
console . log ( "正在执行试用申请..." )
await $ . wait ( args _xh . applyInterval ) ;
for ( let i = 0 ; i < trialActivityIdList . length ; i ++ ) {
args _xh . applyInterval = Math . floor ( Math . random ( ) * ( 4000 ) + 5000 )
await try _apply ( trialActivityTitleList [ i ] , trialActivityIdList [ i ] )
console . log ( ` 间隔延时中,请等待 ${ args _xh . applyInterval } ms \n ` )
await $ . wait ( args _xh . applyInterval ) ;
}
message = message + "<font color=\'#33ff00\' size=2>" + "本循环申请数量:" + trialActivityIdList . length + "总量限制为:" + args _xh . listCount + "</font> </font> \n\n "
trialActivityIdList = [ ]
trialActivityTitleList = [ ]
size = 1
totalPages == 999999
}
console . log ( "试用申请执行完毕..." )
// await try_MyTrials(1, 1) //申请中的商品
await try _MyTrials ( 1 , 2 ) //申请成功的商品
// await try_MyTrials(1, 3) //申请失败的商品
await showMsg ( )
//下一个要重新去拉列表
trialActivityIdList = [ ]
trialActivityTitleList = [ ]
await $ . wait ( Math . floor ( Math . random ( ) * ( 15000 ) + 5000 ) ) ;
}
args _xh . listCount = 0
postToDingTalk ( message )
message = ""
totalPages == 999999
}
await $ . notify . sendNotify ( ` ${ $ . name } ` , notifyMsg ) ;
} else {
console . log ( ` \n 您未设置运行【京东试用】脚本,结束运行! \n ` )
}
} ) ( ) . catch ( ( e ) => {
postToDingTalk ( e + message )
console . log ( ` ❗️ ${ $ . name } 运行错误! \n ${ e } ` )
} ) . finally ( ( ) => {
$ . done ( )
} )
function getList ( ) {
for ( i = 0 ; i < Math . floor ( Math . random ( ) * ( 5001 ) + 500 ) ; i ++ ) {
index1 = Math . floor ( Math . random ( ) * ( args _xh . channel . length ) + 0 )
index2 = Math . floor ( Math . random ( ) * ( args _xh . channel . length ) + 0 )
temp = args _xh . channel [ index1 ]
args _xh . channel [ index1 ] = args _xh . channel [ index2 ]
args _xh . channel [ index2 ] = temp
}
return args _xh . channel . slice ( 0 , args _xh . channelEnd )
}
function requireConfig ( ) {
return new Promise ( resolve => {
console . log ( '开始获取配置文件\n' )
$ . notify = $ . isNode ( ) ? require ( './sendNotify' ) : { sendNotify : async ( ) => { } }
//获取 Cookies
$ . cookiesArr = [ ]
if ( $ . isNode ( ) ) {
//Node.js用户请在jdCookie.js处填写京东ck;
const jdCookieNode = require ( './jdCookie.js' ) ;
Object . keys ( jdCookieNode ) . forEach ( ( item ) => {
if ( jdCookieNode [ item ] ) {
$ . cookiesArr . push ( jdCookieNode [ item ] )
}
} )
if ( process . env . JD _DEBUG && process . env . JD _DEBUG === 'false' ) console . log = ( ) => { } ;
} else {
//IOS等用户直接用NobyDa的jd $.cookie
$ . cookiesArr = [ $ . getdata ( 'CookieJD' ) , $ . getdata ( 'CookieJD2' ) , ... jsonParse ( $ . getdata ( 'CookiesJD' ) || "[]" ) . map ( item => item . cookie ) ] . filter ( item => ! ! item ) ;
}
console . log ( ` 共 ${ $ . cookiesArr . length } 个京东账号 \n ` )
for ( const key in args _xh ) {
if ( typeof args _xh [ key ] == 'string' ) {
args _xh [ key ] = Number ( args _xh [ key ] )
}
}
// console.debug(args_xh)
resolve ( )
} )
}
//获取商品列表并且过滤 By X1a0He
function try _feedsList ( tabId , page ) {
return new Promise ( ( resolve , reject ) => {
const body = JSON . stringify ( {
"tabId" : ` ${ tabId } ` ,
"page" : page ,
"previewTime" : ""
} ) ;
let option = taskurl _xh ( 'newtry' , 'try_feedsList' , body )
$ . get ( option , ( err , resp , data ) => {
try {
if ( err ) {
console . log ( ` 🚫 ${ arguments . callee . name . toString ( ) } API请求失败,请检查网路 \n ${ JSON . stringify ( err ) } ` )
} else {
// console.debug(data)
// return
data = JSON . parse ( data )
if ( totalPages == 999999 ) {
message = message + "<font color=\'#FF0000\' size=2>" + " 当前最大页数为:" + data . data . pages + "</font> </font> \n\n"
}
if ( data . success ) {
$ . totalPages = data . data . pages
totalPages = data . data . pages
console . log ( ` 获取到商品 ${ data . data . feedList . length } 条 \n ` )
for ( let i = 0 ; i < data . data . feedList . length ; i ++ ) {
if ( args _xh . listCount + trialActivityIdList . length >= args _xh . maxLength ) {
console . log ( '商品列表长度已满.结束获取' )
} else
if ( data . data . feedList [ i ] . applyState === 1 ) {
console . log ( ` 商品已申请试用: ${ data . data . feedList [ i ] . skuTitle } ` )
continue
} else
if ( data . data . feedList [ i ] . applyState !== null ) {
console . log ( ` 商品状态异常,跳过: ${ data . data . feedList [ i ] . skuTitle } ` )
continue
} else
if ( data . data . feedList [ i ] . skuTitle ) {
console . log ( ` 检测第 ${ page } 页 第 ${ i + 1 } 个商品 \n ${ data . data . feedList [ i ] . skuTitle } ` )
if ( parseFloat ( data . data . feedList [ i ] . jdPrice ) <= args _xh . jdPrice ) {
console . log ( ` 商品被过滤, ${ data . data . feedList [ i ] . jdPrice } < ${ args _xh . jdPrice } \n ` )
} else if ( parseFloat ( data . data . feedList [ i ] . supplyNum ) > args _xh . minSupplyNum && data . data . feedList [ i ] . supplyNum !== null ) {
console . log ( ` 商品被过滤,提供申请的份数大于预设申请的份数 \n ` )
} else if ( parseFloat ( data . data . feedList [ i ] . applyNum ) > args _xh . applyNumFilter && data . data . feedList [ i ] . applyNum !== null ) {
console . log ( ` 商品被过滤,已申请试用人数大于预设人数 \n ` )
} else if ( parseFloat ( data . data . feedList [ i ] . trialPrice ) > args _xh . trialPrice && data . data . feedList [ i ] . jdPrice < minItemValue ) {
console . log ( ` 商品被过滤,期待价格高于预设价格 \n ` )
} else if ( args _xh . titleFilters . some ( fileter _word => data . data . feedList [ i ] . skuTitle . includes ( fileter _word ) ) ) {
sensMessage += "<font color=\'#FF0000\' size=2>" + data . data . feedList [ i ] . skuTitle + "</font> </font> \n\n"
args _xh . titleFilters . some ( fileter _word => {
if ( data . data . feedList [ i ] . skuTitle . includes ( fileter _word ) ) {
sensMessage += "<font color=\'#000099\' size=2>" + "敏感词汇:" + fileter _word + "</font> </font> \n\n"
}
} )
console . log ( '商品被过滤,含有关键词 \n' )
} else {
console . log ( ` 商品通过,将加入试用组,trialActivityId为 ${ data . data . feedList [ i ] . trialActivityId } \n ` )
trialActivityIdList . push ( data . data . feedList [ i ] . trialActivityId )
trialActivityTitleList . push ( data . data . feedList [ i ] . skuTitle )
}
} else {
console . log ( 'skuTitle解析异常' )
return
}
}
console . log ( ` 当前试用组id如下,长度为: ${ trialActivityIdList . length } \n ${ trialActivityIdList } \n ` )
} else {
console . log ( ` 💩 获得试用列表失败: ${ data . message } ` )
}
}
} catch ( e ) {
console . log ( e ) ;
reject ( ` ⚠️ ${ arguments . callee . name . toString ( ) } API返回结果解析出错 \n ${ e } \n ${ JSON . stringify ( data ) } ` )
console . log ( ` ${ JSON . stringify ( data ) } ` )
} finally {
resolve ( )
}
} )
} )
}
function try _apply ( title , activityId ) {
return new Promise ( ( resolve , reject ) => {
console . log ( ` 申请试用商品中... ` )
console . log ( ` 商品: ${ title } ` )
console . log ( ` id为: ${ activityId } ` )
const body = JSON . stringify ( {
"activityId" : activityId ,
"previewTime" : ""
} ) ;
let option = taskurl _xh ( 'newtry' , 'try_apply' , body )
$ . get ( option , ( err , resp , data ) => {
try {
if ( err ) {
console . log ( ` 🚫 ${ arguments . callee . name . toString ( ) } API请求失败,请检查网路 \n ${ JSON . stringify ( err ) } ` )
} else {
$ . totalTry ++
data = JSON . parse ( data )
if ( data . success && data . code === "1" ) { // 申请成功
message += "<font color=\'#778899\' size=2>" + title + "</font>\n\n"
message += "<font color=\'#778899\' size=2>" + ` ------- \n \n ` + "</font>\n\n"
console . log ( data . message )
$ . totalSuccess ++
} else if ( data . code === "-106" ) {
console . log ( data . message ) // 未在申请时间内!
} else if ( data . code === "-110" ) {
console . log ( data . message ) // 您的申请已成功提交,请勿重复申请…
} else if ( data . code === "-120" ) {
console . log ( data . message ) // 您还不是会员,本品只限会员申请试用,请注册会员后申请!
} else if ( data . code === "-167" ) {
console . log ( data . message ) // 抱歉,此试用需为种草官才能申请。查看下方详情了解更多。
} else {
console . log ( "申请失败" , JSON . stringify ( data ) )
message += "<font color=\'#778899\' size=2>" + JSON . stringify ( data ) + "</font>\n\n"
message += "<font color=\'#778899\' size=2>" + ` ------- \n \n ` + "</font>\n\n"
}
}
} catch ( e ) {
reject ( ` ⚠️ ${ arguments . callee . name . toString ( ) } API返回结果解析出错 \n ${ e } \n ${ JSON . stringify ( data ) } ` )
} finally {
resolve ( )
}
} )
} )
}
function try _MyTrials ( page , selected ) {
return new Promise ( ( resolve , reject ) => {
switch ( selected ) {
case 1 :
console . log ( '正在获取已申请的商品...' )
break ;
case 2 :
console . log ( '正在获取申请成功的商品...' )
break ;
case 3 :
console . log ( '正在获取申请失败的商品...' )
break ;
default :
console . log ( 'selected错误' )
}
const body = JSON . stringify ( {
"page" : page ,
"selected" : selected , // 1 - 已申请 2 - 成功列表,3 - 失败列表
"previewTime" : ""
} ) ;
let option = taskurl _xh ( 'newtry' , 'try_MyTrials' , body )
option . headers . Referer = 'https://pro.m.jd.com/'
$ . get ( option , ( err , resp , data ) => {
try {
if ( err ) {
console . log ( ` 🚫 ${ arguments . callee . name . toString ( ) } API请求失败,请检查网路 \n ${ JSON . stringify ( err ) } ` )
} else {
// console.log(data)
// return
data = JSON . parse ( data )
if ( data . success ) {
//temp adjustment
if ( selected == 2 ) {
if ( data . success && data . data ) {
$ . successList = data . data . list . filter ( item => {
return item . text . text . includes ( '试用资格将保留10天' )
} )
console . log ( ` 待领取: ${ $ . successList . length } 个 ` )
} else {
console . log ( ` 获得成功列表失败: ${ data . message } ` )
}
}
if ( data . data . list . length > 0 ) {
let count = 0
for ( let item of data . data . list ) {
console . log ( ` 申请时间: ${ new Date ( parseInt ( item . applyTime ) ) . toLocaleString ( ) } ` )
console . log ( ` 申请商品: ${ item . trialName } ` )
console . log ( ` 当前状态: ${ item . text . text } ` )
console . log ( ` 剩余时间: ${ remaining ( item . leftTime ) } ` )
if ( count < 3 ) {
message += "<font color=\'#4B0082\' size=1>" + ` 申请商品: ${ item . trialName } ` + "</font>\n\n"
message += "<font color=\'#4B0082\' size=1>" + ` 当前状态: ${ item . text . text } ` + "</font>\n\n"
message += "<font color=\'#4B0082\' size=1>" + ` ----- \n \n ` + "</font>\n\n"
count ++
}
console . log ( )
}
}
// else {
// switch(selected){
// case 1:
// console.log('无已申请的商品\n')
// break;
// case 2:
// console.log('无申请成功的商品\n')
// break;
// case 3:
// console.log('无申请失败的商品\n')
// break;
// default:
// console.log('selected错误')
// }
// }
} else {
console . log ( ` ERROR:try_MyTrials ` )
}
}
} catch ( e ) {
reject ( ` ⚠️ ${ arguments . callee . name . toString ( ) } API返回结果解析出错 \n ${ e } \n ${ JSON . stringify ( data ) } ` )
} finally {
resolve ( )
}
} )
} )
}
function remaining ( time ) {
let days = parseInt ( time / ( 1000 * 60 * 60 * 24 ) ) ;
let hours = parseInt ( ( time % ( 1000 * 60 * 60 * 24 ) ) / ( 1000 * 60 * 60 ) ) ;
let minutes = parseInt ( ( time % ( 1000 * 60 * 60 ) ) / ( 1000 * 60 ) ) ;
return ` ${ days } 天 ${ hours } 小时 ${ minutes } 分 `
}
function taskurl _xh ( appid , functionId , body = JSON . stringify ( { } ) ) {
return {
"url" : ` ${ URL } ?appid= ${ appid } &functionId= ${ functionId } &clientVersion=10.1.2&client=wh5&body= ${ encodeURIComponent ( body ) } ` ,
'headers' : {
'Host' : 'api.m.jd.com' ,
'Accept-Encoding' : 'gzip, deflate, br' ,
'Cookie' : $ . cookie ,
'Connection' : 'keep-alive' ,
'UserAgent' : 'jdapp;iPhone;10.1.2;15.0;ff2caa92a8529e4788a34b3d8d4df66d9573f499;network/wifi;model/iPhone13,4;addressid/2074196292;appBuild/167802;jdSupportDarkMode/1;Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1' ,
'Accept-Language' : 'zh-cn' ,
'Referer' : 'https://prodev.m.jd.com/'
} ,
}
}
async function showMsg ( ) {
let message1 = ` 京东账号 ${ $ . index } ${ $ . nickName || $ . UserName } \n 🎉 本次申请: ${ $ . totalSuccess } / ${ $ . totalTry } 个商品🛒 \n 🎉 ${ $ . successList . length } 个商品待领取 `
message += "<font color=\'#778899\' size=2>" + ` 🎉 本次申请: ${ $ . totalSuccess } / ${ $ . totalTry } 个商品🛒 \n 🎉 ${ $ . successList . length } 个商品待领取 ` + "</font>\n\n"
if ( ! args _xh . jdNotify || args _xh . jdNotify === 'false' ) {
$ . msg ( $ . name , ` ` , message1 , {
"open-url" : 'https://try.m.jd.com/user'
} )
if ( $ . isNode ( ) )
notifyMsg += ` ${ message1 } \n \n `
} else {
console . log ( message1 )
}
}
function totalBean ( ) {
return new Promise ( async resolve => {
const options = {
"url" : ` https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2 ` ,
"headers" : {
"Accept" : "application/json,text/plain, */*" ,
"Content-Type" : "application/x-www-form-urlencoded" ,
"Accept-Encoding" : "gzip, deflate, br" ,
"Accept-Language" : "zh-cn" ,
"Connection" : "keep-alive" ,
"Cookie" : $ . cookie ,
"Referer" : "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2" ,
"User-Agent" : $ . isNode ( ) ? ( process . env . JD _USER _AGENT ? process . env . JD _USER _AGENT : ( require ( './USER_AGENTS' ) . USER _AGENT ) ) : ( $ . getdata ( 'JDUA' ) ? $ . getdata ( 'JDUA' ) : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1" )
} ,
"timeout" : 10000 ,
}
$ . post ( options , ( err , resp , data ) => {
try {
if ( err ) {
console . log ( ` ${ JSON . stringify ( err ) } ` )
console . log ( ` ${ $ . name } API请求失败,请检查网路重试 ` )
} else {
if ( data ) {
data = JSON . parse ( data ) ;
if ( data [ 'retcode' ] === 13 ) {
$ . isLogin = false ; //cookie过期
return
}
if ( data [ 'retcode' ] === 0 ) {
$ . nickName = ( data [ 'base' ] && data [ 'base' ] . nickname ) || $ . UserName ;
} else {
$ . nickName = $ . UserName
}
} else {
console . log ( ` 京东服务器返回空数据 ` )
}
}
} catch ( e ) {
$ . logErr ( e , resp )
} finally {
resolve ( ) ;
}
} )
} )
}
function jsonParse ( str ) {
if ( typeof str == "string" ) {
try {
return JSON . parse ( str ) ;
} catch ( e ) {
console . log ( e ) ;
$ . msg ( $ . name , '' , '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie' )
return [ ] ;
}
}
}
// 来自 @chavyleung 大佬
// https://raw.githubusercontent.com/chavyleung/scripts/master/Env.js
function Env ( name , opts ) {
class Http {
constructor ( env ) {
this . env = env
}
send ( opts , method = 'GET' ) {
opts = typeof opts === 'string' ? {
url : opts
} : opts
let sender = this . get
if ( method === 'POST' ) {
sender = this . post
}
return new Promise ( ( resolve , reject ) => {
sender . call ( this , opts , ( err , resp , body ) => {
if ( err ) reject ( err )
else resolve ( resp )
} )
} )
}
get ( opts ) {
return this . send . call ( this . env , opts )
}
post ( opts ) {
return this . send . call ( this . env , opts , 'POST' )
}
}
return new ( class {
constructor ( name , opts ) {
this . name = name
this . http = new Http ( this )
this . data = null
this . dataFile = 'box.dat'
this . logs = [ ]
this . isMute = false
this . isNeedRewrite = false
this . logSeparator = '\n'
this . startTime = new Date ( ) . getTime ( )
Object . assign ( this , opts )
this . log ( '' , ` 🔔 ${ this . name } , 开始! ` )
}
isNode ( ) {
return 'undefined' !== typeof module && ! ! module . exports
}
isQuanX ( ) {
return 'undefined' !== typeof $task
}
isSurge ( ) {
return 'undefined' !== typeof $httpClient && 'undefined' === typeof $loon
}
isLoon ( ) {
return 'undefined' !== typeof $loon
}
toObj ( str , defaultValue = null ) {
try {
return JSON . parse ( str )
} catch {
return defaultValue
}
}
toStr ( obj , defaultValue = null ) {
try {
return JSON . stringify ( obj )
} catch {
return defaultValue
}
}
getjson ( key , defaultValue ) {
let json = defaultValue
const val = this . getdata ( key )
if ( val ) {
try {
json = JSON . parse ( this . getdata ( key ) )
} catch { }
}
return json
}
setjson ( val , key ) {
try {
return this . setdata ( JSON . stringify ( val ) , key )
} catch {
return false
}
}
getScript ( url ) {
return new Promise ( ( resolve ) => {
this . get ( {
url
} , ( err , resp , body ) => resolve ( body ) )
} )
}
runScript ( script , runOpts ) {
return new Promise ( ( resolve ) => {
let httpapi = this . getdata ( '@chavy_boxjs_userCfgs.httpapi' )
httpapi = httpapi ? httpapi . replace ( /\n/g , '' ) . trim ( ) : httpapi
let httpapi _timeout = this . getdata ( '@chavy_boxjs_userCfgs.httpapi_timeout' )
httpapi _timeout = httpapi _timeout ? httpapi _timeout * 1 : 20
httpapi _timeout = runOpts && runOpts . timeout ? runOpts . timeout : httpapi _timeout
const [ key , addr ] = httpapi . split ( '@' )
const opts = {
url : ` http:// ${ addr } /v1/scripting/evaluate ` ,
body : {
script _text : script ,
mock _type : 'cron' ,
timeout : httpapi _timeout
} ,
headers : {
'X-Key' : key ,
'Accept' : '*/*'
}
}
this . post ( opts , ( err , resp , body ) => resolve ( body ) )
} ) . catch ( ( e ) => this . logErr ( e ) )
}
loaddata ( ) {
if ( this . isNode ( ) ) {
this . fs = this . fs ? this . fs : require ( 'fs' )
this . path = this . path ? this . path : require ( 'path' )
const curDirDataFilePath = this . path . resolve ( this . dataFile )
const rootDirDataFilePath = this . path . resolve ( process . cwd ( ) , this . dataFile )
const isCurDirDataFile = this . fs . existsSync ( curDirDataFilePath )
const isRootDirDataFile = ! isCurDirDataFile && this . fs . existsSync ( rootDirDataFilePath )
if ( isCurDirDataFile || isRootDirDataFile ) {
const datPath = isCurDirDataFile ? curDirDataFilePath : rootDirDataFilePath
try {
return JSON . parse ( this . fs . readFileSync ( datPath ) )
} catch ( e ) {
return { }
}
} else return { }
} else return { }
}
writedata ( ) {
if ( this . isNode ( ) ) {
this . fs = this . fs ? this . fs : require ( 'fs' )
this . path = this . path ? this . path : require ( 'path' )
const curDirDataFilePath = this . path . resolve ( this . dataFile )
const rootDirDataFilePath = this . path . resolve ( process . cwd ( ) , this . dataFile )
const isCurDirDataFile = this . fs . existsSync ( curDirDataFilePath )
const isRootDirDataFile = ! isCurDirDataFile && this . fs . existsSync ( rootDirDataFilePath )
const jsondata = JSON . stringify ( this . data )
if ( isCurDirDataFile ) {
this . fs . writeFileSync ( curDirDataFilePath , jsondata )
} else if ( isRootDirDataFile ) {
this . fs . writeFileSync ( rootDirDataFilePath , jsondata )
} else {
this . fs . writeFileSync ( curDirDataFilePath , jsondata )
}
}
}
lodash _get ( source , path , defaultValue = undefined ) {
const paths = path . replace ( /\[(\d+)\]/g , '.$1' ) . split ( '.' )
let result = source
for ( const p of paths ) {
result = Object ( result ) [ p ]
if ( result === undefined ) {
return defaultValue
}
}
return result
}
lodash _set ( obj , path , value ) {
if ( Object ( obj ) !== obj ) return obj
if ( ! Array . isArray ( path ) ) path = path . toString ( ) . match ( /[^.[\]]+/g ) || [ ]
path . slice ( 0 , - 1 ) . reduce ( ( a , c , i ) => ( Object ( a [ c ] ) === a [ c ] ? a [ c ] : ( a [ c ] = Math . abs ( path [ i + 1 ] ) >> 0 === + path [ i + 1 ] ? [ ] : { } ) ) , obj ) [
path [ path . length - 1 ]
] = value
return obj
}
getdata ( key ) {
let val = this . getval ( key )
// 如果以 @
if ( /^@/ . test ( key ) ) {
const [ , objkey , paths ] = /^@(.*?)\.(.*?)$/ . exec ( key )
const objval = objkey ? this . getval ( objkey ) : ''
if ( objval ) {
try {
const objedval = JSON . parse ( objval )
val = objedval ? this . lodash _get ( objedval , paths , '' ) : val
} catch ( e ) {
val = ''
}
}
}
return val
}
setdata ( val , key ) {
let issuc = false
if ( /^@/ . test ( key ) ) {
const [ , objkey , paths ] = /^@(.*?)\.(.*?)$/ . exec ( key )
const objdat = this . getval ( objkey )
const objval = objkey ? ( objdat === 'null' ? null : objdat || '{}' ) : '{}'
try {
const objedval = JSON . parse ( objval )
this . lodash _set ( objedval , paths , val )
issuc = this . setval ( JSON . stringify ( objedval ) , objkey )
} catch ( e ) {
const objedval = { }
this . lodash _set ( objedval , paths , val )
issuc = this . setval ( JSON . stringify ( objedval ) , objkey )
}
} else {
issuc = this . setval ( val , key )
}
return issuc
}
getval ( key ) {
if ( this . isSurge ( ) || this . isLoon ( ) ) {
return $persistentStore . read ( key )
} else if ( this . isQuanX ( ) ) {
return $prefs . valueForKey ( key )
} else if ( this . isNode ( ) ) {
this . data = this . loaddata ( )
return this . data [ key ]
} else {
return ( this . data && this . data [ key ] ) || null
}
}
setval ( val , key ) {
if ( this . isSurge ( ) || this . isLoon ( ) ) {
return $persistentStore . write ( val , key )
} else if ( this . isQuanX ( ) ) {
return $prefs . setValueForKey ( val , key )
} else if ( this . isNode ( ) ) {
this . data = this . loaddata ( )
this . data [ key ] = val
this . writedata ( )
return true
} else {
return ( this . data && this . data [ key ] ) || null
}
}
initGotEnv ( opts ) {
this . got = this . got ? this . got : require ( 'got' )
this . cktough = this . cktough ? this . cktough : require ( 'tough-cookie' )
this . ckjar = this . ckjar ? this . ckjar : new this . cktough . CookieJar ( )
if ( opts ) {
opts . headers = opts . headers ? opts . headers : { }
if ( undefined === opts . headers . Cookie && undefined === opts . cookieJar ) {
opts . cookieJar = this . ckjar
}
}
}
get ( opts , callback = ( ) => { } ) {
if ( opts . headers ) {
delete opts . headers [ 'Content-Type' ]
delete opts . headers [ 'Content-Length' ]
}
if ( this . isSurge ( ) || this . isLoon ( ) ) {
if ( this . isSurge ( ) && this . isNeedRewrite ) {
opts . headers = opts . headers || { }
Object . assign ( opts . headers , {
'X-Surge-Skip-Scripting' : false
} )
}
$httpClient . get ( opts , ( err , resp , body ) => {
if ( ! err && resp ) {
resp . body = body
resp . statusCode = resp . status
}
callback ( err , resp , body )
} )
} else if ( this . isQuanX ( ) ) {
if ( this . isNeedRewrite ) {
opts . opts = opts . opts || { }
Object . assign ( opts . opts , {
hints : false
} )
}
$task . fetch ( opts ) . then (
( resp ) => {
const {
statusCode : status ,
statusCode ,
headers ,
body
} = resp
callback ( null , {
status ,
statusCode ,
headers ,
body
} , body )
} ,
( err ) => callback ( err )
)
} else if ( this . isNode ( ) ) {
this . initGotEnv ( opts )
this . got ( opts ) . on ( 'redirect' , ( resp , nextOpts ) => {
try {
if ( resp . headers [ 'set-cookie' ] ) {
const ck = resp . headers [ 'set-cookie' ] . map ( this . cktough . Cookie . parse ) . toString ( )
if ( ck ) {
this . ckjar . setCookieSync ( ck , null )
}
nextOpts . cookieJar = this . ckjar
}
} catch ( e ) {
this . logErr ( e )
}
// this.ckjar.setCookieSync(resp.headers['set-cookie'].map(Cookie.parse).toString())
} ) . then (
( resp ) => {
const {
statusCode : status ,
statusCode ,
headers ,
body
} = resp
callback ( null , {
status ,
statusCode ,
headers ,
body
} , body )
} ,
( err ) => {
const {
message : error ,
response : resp
} = err
callback ( error , resp , resp && resp . body )
}
)
}
}
post ( opts , callback = ( ) => { } ) {
// 如果指定了请求体, 但没指定`Content-Type`, 则自动生成
if ( opts . body && opts . headers && ! opts . headers [ 'Content-Type' ] ) {
opts . headers [ 'Content-Type' ] = 'application/x-www-form-urlencoded'
}
if ( opts . headers ) delete opts . headers [ 'Content-Length' ]
if ( this . isSurge ( ) || this . isLoon ( ) ) {
if ( this . isSurge ( ) && this . isNeedRewrite ) {
opts . headers = opts . headers || { }
Object . assign ( opts . headers , {
'X-Surge-Skip-Scripting' : false
} )
}
$httpClient . post ( opts , ( err , resp , body ) => {
if ( ! err && resp ) {
resp . body = body
resp . statusCode = resp . status
}
callback ( err , resp , body )
} )
} else if ( this . isQuanX ( ) ) {
opts . method = 'POST'
if ( this . isNeedRewrite ) {
opts . opts = opts . opts || { }
Object . assign ( opts . opts , {
hints : false
} )
}
$task . fetch ( opts ) . then (
( resp ) => {
const {
statusCode : status ,
statusCode ,
headers ,
body
} = resp
callback ( null , {
status ,
statusCode ,
headers ,
body
} , body )
} ,
( err ) => callback ( err )
)
} else if ( this . isNode ( ) ) {
this . initGotEnv ( opts )
const {
url ,
... _opts
} = opts
this . got . post ( url , _opts ) . then (
( resp ) => {
const {
statusCode : status ,
statusCode ,
headers ,
body
} = resp
callback ( null , {
status ,
statusCode ,
headers ,
body
} , body )
} ,
( err ) => {
const {
message : error ,
response : resp
} = err
callback ( error , resp , resp && resp . body )
}
)
}
}
/**
*
* 示例:$.time('yyyy-MM-dd qq HH:mm:ss.S')
* :$.time('yyyyMMddHHmmssS')
* y:年 M:月 d:日 q:季 H:时 m:分 s:秒 S:毫秒
* 其中y可选0-4位占位符、S可选0-1位占位符,其余可选0-2位占位符
* @param {*} fmt 格式化参数
*
*/
time ( fmt ) {
let o = {
'M+' : new Date ( ) . getMonth ( ) + 1 ,
'd+' : new Date ( ) . getDate ( ) ,
'H+' : new Date ( ) . getHours ( ) ,
'm+' : new Date ( ) . getMinutes ( ) ,
's+' : new Date ( ) . getSeconds ( ) ,
'q+' : Math . floor ( ( new Date ( ) . getMonth ( ) + 3 ) / 3 ) ,
'S' : new Date ( ) . getMilliseconds ( )
}
if ( /(y+)/ . test ( fmt ) ) fmt = fmt . replace ( RegExp . $1 , ( new Date ( ) . getFullYear ( ) + '' ) . substr ( 4 - RegExp . $1 . length ) )
for ( let k in o )
if ( new RegExp ( '(' + k + ')' ) . test ( fmt ) )
fmt = fmt . replace ( RegExp . $1 , RegExp . $1 . length == 1 ? o [ k ] : ( '00' + o [ k ] ) . substr ( ( '' + o [ k ] ) . length ) )
return fmt
}
/**
* 系统通知
*
* > 通知参数: 同时支持 QuanX 和 Loon 两种格式, EnvJs根据运行环境自动转换, Surge 环境不支持多媒体通知
*
* 示例:
* $.msg(title, subt, desc, 'twitter://')
* $.msg(title, subt, desc, { 'open-url': 'twitter://', 'media-url': 'https://github.githubassets.com/images/modules/open_graph/github-mark.png' })
* $.msg(title, subt, desc, { 'open-url': 'https://bing.com', 'media-url': 'https://github.githubassets.com/images/modules/open_graph/github-mark.png' })
*
* @param {*} title 标题
* @param {*} subt 副标题
* @param {*} desc 通知详情
* @param {*} opts 通知参数
*
*/
msg ( title = name , subt = '' , desc = '' , opts ) {
const toEnvOpts = ( rawopts ) => {
if ( ! rawopts ) return rawopts
if ( typeof rawopts === 'string' ) {
if ( this . isLoon ( ) ) return rawopts
else if ( this . isQuanX ( ) ) return {
'open-url' : rawopts
}
else if ( this . isSurge ( ) ) return {
url : rawopts
}
else return undefined
} else if ( typeof rawopts === 'object' ) {
if ( this . isLoon ( ) ) {
let openUrl = rawopts . openUrl || rawopts . url || rawopts [ 'open-url' ]
let mediaUrl = rawopts . mediaUrl || rawopts [ 'media-url' ]
return {
openUrl ,
mediaUrl
}
} else if ( this . isQuanX ( ) ) {
let openUrl = rawopts [ 'open-url' ] || rawopts . url || rawopts . openUrl
let mediaUrl = rawopts [ 'media-url' ] || rawopts . mediaUrl
return {
'open-url' : openUrl ,
'media-url' : mediaUrl
}
} else if ( this . isSurge ( ) ) {
let openUrl = rawopts . url || rawopts . openUrl || rawopts [ 'open-url' ]
return {
url : openUrl
}
}
} else {
return undefined
}
}
if ( ! this . isMute ) {
if ( this . isSurge ( ) || this . isLoon ( ) ) {
$notification . post ( title , subt , desc , toEnvOpts ( opts ) )
} else if ( this . isQuanX ( ) ) {
$notify ( title , subt , desc , toEnvOpts ( opts ) )
}
}
if ( ! this . isMuteLog ) {
let logs = [ '' , '==============📣系统通知📣==============' ]
logs . push ( title )
subt ? logs . push ( subt ) : ''
desc ? logs . push ( desc ) : ''
console . log ( logs . join ( '\n' ) )
this . logs = this . logs . concat ( logs )
}
}
log ( ... logs ) {
if ( logs . length > 0 ) {
this . logs = [ ... this . logs , ... logs ]
}
console . log ( logs . join ( this . logSeparator ) )
}
logErr ( err , msg ) {
const isPrintSack = ! this . isSurge ( ) && ! this . isQuanX ( ) && ! this . isLoon ( )
if ( ! isPrintSack ) {
this . log ( '' , ` ❗️ ${ this . name } , 错误! ` , err )
} else {
this . log ( '' , ` ❗️ ${ this . name } , 错误! ` , err . stack )
}
}
wait ( time ) {
return new Promise ( ( resolve ) => setTimeout ( resolve , time ) )
}
done ( val = { } ) {
const endTime = new Date ( ) . getTime ( )
const costTime = ( endTime - this . startTime ) / 1000
this . log ( '' , ` 🔔 ${ this . name } , 结束! 🕛 ${ costTime } 秒 ` )
this . log ( )
if ( this . isSurge ( ) || this . isQuanX ( ) || this . isLoon ( ) ) {
$done ( val )
}
}
} ) ( name , opts )
}
//我加的函数
function postToDingTalk ( messgae ) {
const message1 = "" + messgae
// that.log(messgae)
const body = {
"msgtype" : "markdown" ,
"markdown" : {
"title" : "随机试用" ,
"text" : message1
} ,
"at" : {
"atMobiles" : [ ] ,
"isAtAll" : true
}
}
$ . post ( toDingtalk ( dingtalk , JSON . stringify ( body ) ) , ( data , status , xhr ) => {
try {
that . log ( resp )
that . log ( data )
if ( err ) {
that . log ( JSON . stringify ( err ) ) ;
$ . logErr ( err ) ;
} else {
if ( safeGet ( data ) ) {
$ . duckRes = JSON . parse ( data ) ;
}
}
} catch ( e ) {
$ . logErr ( e , resp )
} finally {
resolve ( ) ;
}
} , "json" )
}
function toDingtalk ( urlmain , bodyMain ) {
return {
url : urlmain ,
body : bodyMain ,
headers : { 'Content-Type' : 'application/json;charset=utf-8' } ,
timeout : 10000 ,
}
}
function postToDingTalk1 ( messgae ) {
const message1 = "" + messgae
// that.log(messgae)
const body = {
"msgtype" : "markdown" ,
"markdown" : {
"title" : "错误筛选" ,
"text" : message1
} ,
"at" : {
"atMobiles" : [ ] ,
"isAtAll" : false
}
}
$ . post ( toDingtalk ( dingtalk1 , JSON . stringify ( body ) ) , ( data , status , xhr ) => {
try {
that . log ( resp )
that . log ( data )
if ( err ) {
that . log ( JSON . stringify ( err ) ) ;
$ . logErr ( err ) ;
} else {
if ( safeGet ( data ) ) {
$ . duckRes = JSON . parse ( data ) ;
}
}
} catch ( e ) {
$ . logErr ( e , resp )
} finally {
resolve ( ) ;
}
} , "json" )
}