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-11-07 01:20:20 +08:00
titleFilters : [ "射灯" , "欧布圣剑" , "超比乐" , "滚梳直柄" , "凝胶糖果" , "DHA藻油" , "水带" , "摘果神器" , "宝宝儿童零食" , "总复习" , "满分冲刺" , "黄冈" , "小状元" , "钓鱼插件" , "寒假作业" , "作业" , "菜罩" , "手机线" , "美容油" , "贺卡" , "眼贴" , "小斗篷" , "小孩子演奏" , "砍柴刀" , "消防应急灯" , "食用色素" , "烘焙彩针糖果" , "德尔地板" , "水管保温套" , "水管道" , "定位器" , "追踪器" , "电瓶" , "快递纸箱" , "尤克里里" , "金龙鱼 面条挂面" , "痛风" , "KVM切换器" , "水泥" , "猫罐头" , "去斑霜" , "0-12岁" , "4/3膜" , "FMJ" , "H10E" , "HDMI" , "HEISHA" , "HPV" , "KB216有线键盘" , "LED" , "MS116 有线鼠标" , "N1162有线鼠标" , "Ockered" , "PVC板" , "SD" , "SD卡" , "SMOVES" , "SUP掌机" , "U盘" , "VGA" , "hdmi" , "hpv" , "led开关电源" , "uv镜" , "win10" , "windows" , "一次性" , "一片装" , "一盒" , "万向滑轮" , "万用表" , "万藓灵" , "三角阀" , "三轮车" , "不干胶标签带" , "专升本" , "专用贴" , "丝袜" , "中国电信" , "中国结" , "中央扶手箱" , "中性水笔" , "中性笔" , "中老年" , "丰胸" , "串珠玩具" , "丸" , "乒乓球" , "九九乘法" , "九九乘除" , "书包" , "乳液" , "乳腺" , "交换" , "交换机" , "产品体验" , "享底价" , "亲子互动" , "亿优信" , "仓鼠零食" , "仿真小蛋糕" , "伊威" , "优盘" , "会员" , "会员卡" , "会议杯子" , "会议记录" , "传菜铃" , "体温计" , "体验装" , "侧挂式" , "便秘" , "保健" , "保护壳" , "保护套" , "保护膜" , "保护镜" , "保暖女裤" , "保暖裤" , "保温棉" , "保鲜膜" , "信封" , "信纸" , "修护" , "修正带" , "修眉" , "修眉剪" , "倒车" , "倒车镜" , "假发" , "假睫毛" , "停车牌" , "健康检测" , "储奶袋" , "儿童n95" , "儿童串珠玩具" , "儿童乐园" , "儿童便捷" , "儿童保温水杯" , "儿童医生" , "儿童口罩" , "儿童吸管" , "儿童奶粉" , "儿童成长" , "儿童拌饭" , "儿童暖暖套" , "儿童椅子" , "儿童沐浴露" , "儿童牙膏" , "儿童玩具枪" , "儿童电动牙刷" , "儿童电话手表" , "儿童益生菌" , "儿童磨牙饼" , "儿童背包" , "儿童随身" , "儿童雨伞" , "充电头" , "充电桩" , "光和青春" , "光驱" , "免钉胶水" , "八倍镜" , "公主项链" , "公文包" , "养芝堂" , "内胆包" , "内衣" , "内裤" , "冰箱贴" , "冰袋" , "冷兵器" , "冷凝胶" , "冷敷贴" , "冻干粉" , "净水剂" , "减关镜" , "减肥" , "凳子套" , "刀头" , "刀片" , "分流" , "分流器" , "分线盒" , "切割片" , "切菜板" , "创可贴" , "刨木" , "别针" , "刮痧" , "刮痧板" , "刷头" , "刷子" , "刷牙头" , "刹车油" , "刺激贴" , "剂" , "剃须刀配件" , "削皮刀" , "前列腺" , "剥虾" , "剪" , "剪钳" , "割草机" , "办公会议茶杯" , "办公宝" , "办公杯" , "加密狗" , "加温器" , "勿拍" , "包皮" , "包装膜" , "化妆" , "匙扣" , "医生" , "半身不遂" , "半身裙" , "单拍不发货" , "卡册" , "卡套" , "卡尺" , "卡托" , "卡牌" , "卡针" , "卧铺垫" , "卸妆" , "卸妆水" , "压差表" , "压片" , "去毛器" , "去角质" , "参肽片" , "双面板" , "反光条贴" , "反光板" , "反光贴" , "反光镜" , "反弹器" , "变身器" , "口琴" , "口红" , "口罩" , "口罩盒" , "口腔" , "口腔抑菌" , "口香糖" , "台灯" , "台账本" , "号码卡" , "吃饭衣" , "合成机油" , "同仁堂" , "后膜" , "启动电源" , "吸奶器" , "吸顶灯" , "告知牌" , "周岁" , "呼噜" , "咖啡豆" , "咬钩" , "咽炎" , "哑光" , "哨" , "哺乳" , "哺乳套装" , "唇釉" , "唑溶液" , "商务休闲" , "啪啪" , "喷壶" , "喷雾器" , "嚼片" , "园艺工具" , "围兜" , "围裙" , "固定器" , "图钉" , "圆珠笔" , "土工布" , "圣杯" , "在线直播" , "地吸" , "地桩" , "地漏" , "地面清洁液" , "坐便器" , "坐便椅" , "坐垫" , "坐骨膏" , "垃圾处理器" , "垃圾袋" , "垫片" , "培训" , "塑料士兵小军人玩具" , "塑料杯" , "塑身裤" , "塔菲克" , "墙纸" , "增生贴" , "增高" , "墨块" , "墨条" , "墨水" , "墨盒" , "墨粉" , "墨镜" , "壁纸" , "声卡套装" , "复合肥" , "外用" , "多功能尺子" , "多色笔" , "大头围" , "天线" , "头皮" , "夹" , "女士内裤" , "女士内裤,少女内裤" , "女童裤子" , "女童靴子" , "奶瓶" , "奶粉" , "如意碗" , "妆" , "妇女" , "婴儿" , "婴幼儿" , "孔明锁" , "孕妇装" , "存储卡" , "学习卡" , "学历" , "学生文具" , "孩儿乐" , "安全帽" , "安全裤" , "安全锤" , "定位器" , "定做" , "定做榻榻
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"
2021-11-03 14:56:35 +08:00
await $ . wait ( Math . floor ( Math . random ( ) * ( 175000 ) + 5000 ) ) ;
2021-10-26 19:20:52 +08:00
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 = "跑腿小弟子"
2021-10-31 00:26:09 +08:00
continue
2021-10-26 19:20:52 +08:00
}
if ( $ . UserName == "jd_66ea783827d30" ) {
username = "军子"
2021-10-31 00:26:09 +08:00
continue
2021-10-26 19:20:52 +08:00
}
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" )
}