Last active
October 24, 2024 06:09
-
-
Save imdong/f3fd44f43a6432bcc9d69f44ddf5ab7e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Apple Store 专卖店库存监控 | |
* | |
* Docker: | |
* 前台运行 $ docker run --rm -it -v $(pwd):/app --name="apple" node:alpine node /app/apple.js | |
* 后台运行 $ docker run --rm -it -d -v $(pwd):/app --name="apple" node:alpine node /app/apple.js | |
* 后台时实时查看日志 $ docker logs -f -n 100 apple | |
* | |
* 需先: npm i axios | |
* | |
* 作者:青石 https://www.qs5.org | |
*/ | |
const axios = require('axios'); | |
const fs = require('fs'); | |
(function (products) { | |
let url = 'https://www.apple.com.cn/shop/fulfillment-messages', | |
parmas = { | |
mt: 'regular', | |
little: 'false', | |
store: 'R484', // 专卖店ID | |
// "parts.0": 'MLT83CH/A', | |
// "parts.1": 'MLT63CH/A' | |
}, | |
bark_state = {}; | |
Object.keys(products).forEach((product, index) => { | |
parmas['parts.' + index] = product; | |
}); | |
axios.defaults.timeout = 10 * 1000; | |
function getInfo() { | |
let date = new Date(); | |
console.log(date); | |
// 保存日志文件 | |
let file = '/app/logs/' + date.toISOString() + '.txt'; | |
axios.get(url, { | |
params: parmas | |
}).then(response => { | |
// console.log(response); | |
// 保存文件 | |
fs.writeFileSync(file, JSON.stringify(response.data)); | |
let productNames = {}, datas = {}; | |
response.data.body.content.pickupMessage.stores.forEach(store => { | |
for (const product in store.partsAvailability) { | |
const productInfo = store.partsAvailability[product]; | |
productNames[product] = productInfo.storePickupProductTitle; | |
datas[product] = { | |
'产品型号': productInfo.storePickupProductTitle, | |
'旗舰店取货': productInfo.pickupSearchQuote + ': ' + productInfo.storePickupQuote.replace(/<[^>]+>/g, ''), | |
}; | |
// 如果有货 马上 提醒 | |
if (productInfo.pickupSearchQuote.indexOf('不可取货') < 0 || productInfo.storePickupQuote.indexOf('不可') < 0) { | |
// 不要删除了 | |
file = null; | |
// 检查是不是发过信息了 (30秒内 只发一次) | |
let now = new Date(); | |
if (bark_state[product] && now - bark_state[product] < 30000) { | |
return; | |
} | |
bark_state[product] = now; | |
// 给列表的每个人发信息 | |
products[product].forEach(bark_url => { | |
let bark_url_send = ''; | |
if (bark_url.indexOf('api.day.app') > 0) { | |
// 发送信息的地址 | |
bark_url_send = `${bark_url}/${encodeURIComponent(productInfo.storePickupProductTitle + ' ' + productInfo.pickupSearchQuote)}/${encodeURIComponent(productInfo.storePickupQuote.replace(/<[^>]+>/g, ''))}`; | |
} else { | |
let content = productInfo.storePickupProductTitle | |
+ ' ' + productInfo.pickupSearchQuote | |
+ "\n" + productInfo.storePickupQuote.replace(/<[^>]+>/g, ''); | |
bark_url_send = `${bark_url}${encodeURIComponent(content)}`; | |
} | |
// 推送 | |
axios.get(bark_url_send).catch(e => console.log(e)).then(response => { | |
// console.log(response); | |
}); | |
}); | |
} | |
} | |
}); | |
// deliveryMessage 快递选项 | |
// for (const product in response.data.body.content.deliveryMessage) { | |
// if (!products[product]) { | |
// continue; | |
// } | |
// const productInfo = response.data.body.content.deliveryMessage[product]; | |
// datas[product] = datas[product] || {}; | |
// // 捕捉这些不对的情况 | |
// let orderByDeliveryBy = productInfo.orderByDeliveryBySuffix || productInfo.orderByDeliveryBy || null; | |
// if (!orderByDeliveryBy || Object.keys(datas[product]).length == 0) { | |
// file = null; | |
// } | |
// datas[product]['快递'] = orderByDeliveryBy.replace(/<[^>]+>/g, '') + productInfo.deliveryOptionMessages[0].displayName; | |
// } | |
console.table(datas); | |
// 保存日资 | |
// datas.date = date; | |
fs.writeFileSync('/app/logs/run.log', `${date.toISOString()}\n\n` + JSON.stringify(datas) + "\n\n"); | |
// 如果没有货 就删除文件 | |
if (file) { | |
fs.unlinkSync(file); | |
} | |
// 延迟一秒再去查询 | |
setTimeout(getInfo, 0); | |
}).catch(err => { | |
fs.writeFileSync('/app/logs/error.log', `${date.toISOString()}\n\n` + JSON.stringify(err) + "\n\n"); | |
setTimeout(getInfo, 500); | |
}); | |
} | |
// 每隔30秒执行一次 | |
// setInterval(getInfo, 30000); | |
// 先查一次 | |
getInfo(); | |
})({ | |
// Pro Max 远峰蓝 256G | |
'MLHC3CH/A': [ | |
'https://api.day.app/xxxxx', | |
], | |
// Pro 远峰蓝 128G | |
'MLT83CH/A': [ | |
'https://api.day.app/xxxxx', | |
], | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment