const HELLO_BIKE = init() const TASK_NAME = '哈啰出行' const TOKEN_KEY = 'hellobike' const API_URL = 'https://gameapi.hellobike.com/api' const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148; app=easybike; version=5.35.0' if (typeof $request !== 'undefined') { getToken() HELLO_BIKE.done() } else { ;(async () => { let token = HELLO_BIKE.getdata(TOKEN_KEY) if (!token) { HELLO_BIKE.msg(TASK_NAME, '请先获取 Token') HELLO_BIKE.done() return } await checkin(token).then(data => { if (data && data.isSuccess) { HELLO_BIKE.msg(TASK_NAME, `签到成功,获取 ${data.energy}c 能量`) } else if (data && !data.isSuccess) { HELLO_BIKE.msg(TASK_NAME, `重复签到`) } }).catch(error => { HELLO_BIKE.msg(TASK_NAME, error.reason) if (error.isInvalidToken) { token = null } }) await share(token).then(data => { HELLO_BIKE.log(TASK_NAME, `分享成功, ${JSON.stringify(data)}`) }).catch(error => { HELLO_BIKE.msg(TASK_NAME, error.reason) if (error.isInvalidToken) { token = null } }) await getEnergyList(token).then( data => { HELLO_BIKE.log(TASK_NAME, `获取能量:${JSON.stringify(data)}`) return mergePromise(data.map(energy => collectEnergy(token, energy.guid))) }, error => { HELLO_BIKE.msg(TASK_NAME, error.reason) if (error.isInvalidToken) { token = null } }, ).then( data => { if (Array.isArray(data) && data.length > 0) { HELLO_BIKE.log(TASK_NAME, `收取能量: ${JSON.stringify(data)}`) let collected = data.filter(energy => { return energy != null }).reduce((total, currentValue) => { return total + currentValue.energy }, 0) HELLO_BIKE.msg(TASK_NAME, `收取能量成功,总共收取 ${collected}c 能量`) } HELLO_BIKE.done() }, error => { HELLO_BIKE.msg(TASK_NAME, error.reason) HELLO_BIKE.done() }, ) })() } function getToken() { if ($request.body) { let body = JSON.parse($request.body) if (body && body.token) { let token = HELLO_BIKE.getdata(TOKEN_KEY) if (token != null) { if (token !== body.token) { if (!HELLO_BIKE.setdata(body.token, TOKEN_KEY)) { HELLO_BIKE.msg(`更新 ${TASK_NAME} Token 失败‼️`) } else { HELLO_BIKE.msg(`更新 ${TASK_NAME} Token 成功 🎉`) } } } else { if (!HELLO_BIKE.setdata(body.token, TOKEN_KEY)) { HELLO_BIKE.msg(`首次写入 ${TASK_NAME} Token 失败‼️`) } else { HELLO_BIKE.msg(`首次写入 ${TASK_NAME} Token 成功 🎉`) } } } } } function checkin(token) { if (!token) { return Promise.resolve({}) } return new Promise((resolve, reject) => { let action = 'happy.energy.dailyCheck.v2' let options = { url: API_URL, headers: { 'User-Agent': UA }, body: JSON.stringify({ action, token, ticket: '', }), } HELLO_BIKE.post(options, (error, response, data) => { if (error) { HELLO_BIKE.log(TASK_NAME, `签到失败,error:${error}`) reject(new RequestFailed(action, error)) return } let result = JSON.parse(data) if (result && result.code === 0 && result.data) { resolve(result.data) } else { HELLO_BIKE.log(TASK_NAME, `签到失败,response:${data}`) reject(new RequestFailed(action, result.msg, result.code === 103)) } }) }) } function share(token) { if (!token) { return Promise.resolve({}) } return new Promise((resolve, reject) => { let action = 'happy.energy.dailyShare' let options = { url: API_URL, headers: { 'User-Agent': UA }, body: JSON.stringify({ token, action, ticket: '', }), } HELLO_BIKE.post(options, (error, response, data) => { if (error) { HELLO_BIKE.log(TASK_NAME, `分享失败,error:${error}`) reject(new RequestFailed(action, error)) return } let result = JSON.parse(data) if (result && result.code === 0) { resolve(result) } else { HELLO_BIKE.log(TASK_NAME, `分享失败,response:${data}`) reject(new RequestFailed(action, result.msg, result.code === 103)) } }) }) } function getEnergyList(token) { if (!token) { return Promise.resolve([]) } return new Promise((resolve, reject) => { let action = 'happy.energy.getEnergyList' let options = { url: API_URL, headers: { 'User-Agent': UA }, body: JSON.stringify({ token, action, ticket: '', limit: 6, }), } HELLO_BIKE.post(options, (error, response, data) => { if (error) { HELLO_BIKE.log(TASK_NAME, `获取能量失败,error:${error}`) reject(new RequestFailed(action, error)) return } let result = JSON.parse(data) if (result && result.code === 0 && result.data) { resolve(result.data) } else { HELLO_BIKE.log(TASK_NAME, `获取能量失败,response:${data}`) reject(new RequestFailed(action, result.msg, result.code === 103)) } }) }) } function collectEnergy(token, energyGuid) { if (!token) { return Promise.resolve({}) } return new Promise((resolve, reject) => { let action = 'happy.energy.collectEnergy' let options = { url: API_URL, headers: { 'User-Agent': UA }, body: JSON.stringify({ token, action, ticket: '', energyGuid, }), } HELLO_BIKE.post(options, (error, response, data) => { if (error) { HELLO_BIKE.log(TASK_NAME, `收取能量失败,error:${error}`) reject(new RequestFailed(action, error)) return } let result = JSON.parse(data) if (result && result.code === 0 && result.data) { resolve(result.data) } else { HELLO_BIKE.log(TASK_NAME, `收取能量失败,response:${data}`) reject(new RequestFailed(action, result.msg, result.code === 103)) } }) }) } function mergePromise(promises = []) { let array = [] let sequence = Promise.resolve([]) promises.forEach(promise => { sequence = sequence.then(() => promise).then(data => { array.push(data) return array }) }) return sequence } function init() { isSurge = () => { return undefined !== this.$httpClient } isQuanX = () => { return undefined !== this.$task } getdata = (key) => { if (isSurge()) return $persistentStore.read(key) if (isQuanX()) return $prefs.valueForKey(key) } setdata = (key, val) => { if (isSurge()) return $persistentStore.write(key, val) if (isQuanX()) return $prefs.setValueForKey(key, val) } msg = (title, subtitle = '', body = '') => { if (isSurge()) $notification.post(title, subtitle, body) if (isQuanX()) $notify(title, subtitle, body) } log = (title, msg) => { console.log(`${title}:\n${msg}\n`) } get = (options, callback) => { if (isQuanX()) { if (typeof options == 'string') options = { url: options } options['method'] = 'GET' return $task.fetch(options).then( response => { response['status'] = response.statusCode callback(null, response, response.body) }, reason => callback(reason.error, null, null), ) } if (isSurge()) return $httpClient.get(options, callback) } post = (options, callback) => { if (isQuanX()) { if (typeof options == 'string') options = { url: options } options['method'] = 'POST' $task.fetch(options).then( response => { response['status'] = response.statusCode callback(null, response, response.body) }, reason => callback(reason.error, null, null), ) } if (isSurge()) $httpClient.post(options, callback) } done = (value = {}) => { $done(value) } return { isSurge, isQuanX, msg, log, getdata, setdata, get, post, done } } function RequestFailed(action = '', reason = '', isInvalidToken = false) { this.action = action this.reason = reason this.isInvalidToken = isInvalidToken } RequestFailed.prototype = { constructor: RequestFailed, }