RSSHub/lib/v2/kuaidi100/utils.js

260 lines
9.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const got = require('@/utils/got');
const wwwid_key = 'kuaidi100-wwwid';
const csrf_key = 'kuaidi100-csrf';
const globacsrftoken_key = 'kuaidi100-globacsrftoken';
const dasddocTitl_key = 'kuaidi100-dasddocTitl';
const dasddocReferrer_key = 'kuaidi100-dasddocReferrer';
const dasddocHref_key = 'kuaidi100-dasddocHref';
const query_count = 'kuaidi100-cookie-count';
const max_query_count = 30;
async function getCookie(ctx) {
// Check if this key should be replace? every 30 times should be fine.
shouldUpdateCookie(ctx);
let wwwid = await ctx.cache.get(wwwid_key);
let csrf = await ctx.cache.get(csrf_key);
let globacsrftoken = await ctx.cache.get(globacsrftoken_key);
let dasddocTitl = await ctx.cache.get(dasddocTitl_key);
let dasddocReferrer = await ctx.cache.get(dasddocReferrer_key);
let dasddocHref = await ctx.cache.get(dasddocHref_key);
if (!wwwid || !csrf || !dasddocTitl || !dasddocReferrer || !dasddocHref) {
const indexResponse = await got({
method: 'get',
url: 'https://www.kuaidi100.com/?from=appstore',
headers: {
// App store
Referer: 'https://apps.apple.com/cn/app/%E5%BF%AB%E9%80%92100-%E5%8F%8C11%E5%AF%84%E4%BB%B6%E9%80%80%E8%B4%A7-%E4%B8%8A%E5%BF%AB%E9%80%92100/id458270120',
},
});
const set_cookie = indexResponse.headers['set-cookie'];
if (set_cookie) {
for (const e of set_cookie) {
// eslint-disable-next-line unicorn/prefer-switch
if (e.indexOf('WWWID') === 0) {
wwwid = e.split(';')[0];
} else if (e.indexOf('csrftoken') === 0) {
csrf = e.split(';')[0];
} else if (e.indexOf('globacsrftoken') === 0) {
globacsrftoken = e.split(';')[0];
} else if (e.includes('dasddocTitle')) {
dasddocTitl = e.split(';')[0];
} else if (e.includes('dasddocReferrer')) {
dasddocReferrer = e.split(';')[0];
} else if (e.includes('dasddocHref')) {
dasddocHref = e.split(';')[0];
}
}
}
ctx.cache.set(wwwid_key, wwwid, 600);
ctx.cache.set(csrf_key, csrf, 600);
ctx.cache.set(globacsrftoken_key, globacsrftoken, 600);
ctx.cache.set(dasddocTitl_key, dasddocTitl, 600);
ctx.cache.set(dasddocReferrer_key, dasddocReferrer, 600);
ctx.cache.set(dasddocHref_key, dasddocHref, 600);
// We have acquired new cookie. It may due to cache timeout.
// Force update counter and don't wait it finished.
shouldUpdateCookie(ctx, true);
}
return {
wwwid,
csrf,
globacsrftoken,
dasddocTitl,
dasddocReferrer,
dasddocHref,
};
}
/*
Example Company
{
"available": false, <- 这个不知道是什么的可用性,反正不是可查询的
"canOrder": false,
"comTypeName": "国内运输商",
"contactTel": "626-818-2750",
"createTime": 1486202888000,
"hasNetwork": false,
"id": 7172420,
"name": "金岸物流",
"number": "jinan",
"shortName": "金岸物流",
"shortNumber": "jinan",
"siteUrl": "http://www.gpl-express.com/",
"type": 0,
"version": 776
}
*/
function getCompanyList(ctx) {
// Using date as cache key and it will automatically expired by 1d
const key = `kuaidi100-company-name-${new Date().toISOString().split('T')[0]}`;
return ctx.cache.tryGet(key, async () => {
const cookie = await getCookie(ctx);
const wwwid = cookie.wwwid;
const companyResponse = await got({
method: 'post',
url: 'https://www.kuaidi100.com/company.do?method=js&t=201701051440',
headers: {
Referer: 'https://www.kuaidi100.com/',
Cookie: wwwid,
},
});
let list = companyResponse.body;
// Parsing the js file
try {
list = list.slice(12).replaceAll('};', '}').replaceAll("'", '"');
list = JSON.parse(list);
list = list.company;
} catch {
throw new Error('无法正确获取快递公司列表:请稍后重试');
}
return list;
});
}
function shouldUpdateCookie(ctx, forcedUpdate = false) {
if (forcedUpdate) {
ctx.cache.set(query_count, 0);
} else {
const count = ctx.cache.get(query_count);
if (count) {
if (count > max_query_count) {
ctx.cache.set(query_count, 0);
clearCookie(ctx);
} else {
ctx.cache.set(query_count, count + 1);
}
} else {
ctx.cache.set(query_count, 1);
}
}
}
function clearCookie(ctx) {
ctx.cache.set(wwwid_key, null);
ctx.cache.set(csrf_key, null);
}
module.exports = {
company: (ctx) => getCompanyList(ctx),
checkCode: async (ctx, number, id, phone) => {
const list = await getCompanyList(ctx);
const company = list.find((c) => c.number === number);
if (company) {
if (number.includes('shunfeng') && !isNaN(phone) && String(phone).length !== 4) {
return {
status: false,
message: '顺丰查询需要手机号后四位!',
company,
};
} else if (company.checkReg) {
return {
status: true,
regex: new RegExp(company.checkReg).test(id),
company,
};
} else {
return {
status: true,
regex: undefined,
company,
};
}
} else {
return {
status: false,
message: '快递公司编号不受支持!',
company: {
name: '未知',
},
};
}
},
/*
Example Query
{
"message": "ok",
"nu": "73123917441103",
"ischeck": "1",
"condition": "F00",
"com": "zhongtong",
"status": "200",
"state": "3",
"data": [{
"time": "2019-12-12 12:41:15",
"ftime": "2019-12-12 12:41:15",
"context": "【温州市】 快件已由【菜鸟的温州燎原华庭7栋103号店】代签收, 如有问题请电联18581563547 / 4001787878, 感谢您使用中通快递, 期待再次为您服务!",
"location": ""
}
...]
Example failed Query
{
"message": "快递公司参数异常:验证码错误",
"nu": "",
"ischeck": "0",
"condition": "",
"com": "",
"status": "408",
"state": "0",
"data": []
}
*/
getQuery: async (ctx, number, id, phone) => {
const query_key = `kuaidi100-query-${number}-${id}`;
let query = await ctx.cache.get(query_key);
// 组装日期与单号 日期为提前两个月
const timestamp = Number.parseInt(Date.now() / 1000);
const lastTowMonth = Date.now() - 60 * 60 * 24 * 60 * 1000;
const dateString = new Date(lastTowMonth).toLocaleDateString('ZH').split('/').join('');
const queryMeta = encodeURIComponent(
JSON.stringify({
date: dateString,
nums: [id],
})
);
if (query) {
query = JSON.parse(query);
} else {
const cookie = await getCookie(ctx);
const queryResponse = await got({
method: 'get',
url: `https://www.kuaidi100.com/query?type=${number}&postid=${id}&temp=${Math.random()}&phone=${phone ?? ''}`,
headers: {
Referer: 'https://www.kuaidi100.com/',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36',
Cookie: `${cookie.globacsrftoken}; ${cookie.csrf}; ${cookie.wwwid}; ${cookie.dasddocHref}; ${cookie.dasddocReferrer}; ${
cookie.dasddocTitl
}; addcom=${number}; addnu=${id}; snt_query_meta=${queryMeta}; sortStatus=0; Hm_lpvt_22ea01af58ba2be0fec7c11b25e88e6c=${timestamp}; Hm_lvt_22ea01af58ba2be0fec7c11b25e88e6c=${timestamp - 1642}`,
},
});
query = queryResponse.data;
if (query.status === '200') {
if (query.data && query.data[0].context === '查无结果') {
// 查无结果 appears when cookie is invaild, force update cookie.
clearCookie(ctx);
throw new Error('暂时无法获取快递信息,请稍后重试...');
} else if (query.ischeck === '0') {
// Not yet complete, don't cache for now.
// To avoid frquent link test when add source, add 180s cache
ctx.cache.set(query_key, query, 180);
} else {
ctx.cache.set(query_key, query); // Finished, cache id
}
} else {
ctx.cache.set(query_key, query); // Error, cache as well
throw new Error(`[${query.status}]信息有误,请重新检查后订阅:${query.message}`);
}
}
return query;
},
};