Skip to content

Commit

Permalink
feat: 支持更多优惠券
Browse files Browse the repository at this point in the history
  • Loading branch information
vv314 committed Dec 31, 2023
1 parent db9b86d commit 0bc3c88
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 98 deletions.
12 changes: 7 additions & 5 deletions src/coupons/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ const ECODE = {
RUNTIME: 4
}

const mainActConf = [
{ gid: '2KAWnD', name: '外卖红包天天领' },
{ gid: '4luWGh', name: '品质优惠天天领' }
const mainActConf = { gid: '2KAWnD', name: '外卖红包天天领' }

const gundamActConfs = [
{ gid: '4luWGh', name: '品质优惠天天领' },
{ gid: '4JZIgf', name: '冬日美食季' }
]

const wxfwhActConf = [
const wxfwhActConfs = [
{ gid: '1C0wLz', name: '天天神券服务号专属福利' },
{ gid: '1HgnjG', name: '365元祝福请收下' },
{ gid: '1I9uL6', name: '美团外卖社群专属福利' }
]

export { ECODE, mainActConf, wxfwhActConf }
export { ECODE, gundamActConfs, mainActConf, wxfwhActConfs }
50 changes: 33 additions & 17 deletions src/coupons/gundamGrab.js → src/coupons/gundam.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,47 @@ import { dateFormat } from '../util/index.js'
import { getTemplateData, getRenderList, matchMoudleData } from '../template.js'
import { ECODE } from './const.js'

async function getPayload(gundamId, appJs, guard) {
const renderList = await getRenderList(gundamId, guard)
const jsText = await fetch(appJs).then((res) => res.text())
let data = null

function resolveRedMod(text, renderList) {
try {
for (const instanceId of renderList) {
data = matchMoudleData(
jsText,
`gdc-fx-v2-netunion-red-envelope-${instanceId}`,
'isStopTJCoupon'
)
const data =
matchMoudleData(
text,
`gdc-fx-v2-netunion-red-envelope-${instanceId}`,
'isStopTJCoupon'
) ??
matchMoudleData(
text,
`gdc-fx-new-netunion-red-envelope-${instanceId}`,
'isStopTJCoupon'
)

if (data) {
data.instanceID = instanceId
data.isStopTJCoupon = true

break
return data
}
}
} catch {
// ignore
}

return null
}

async function getPayload(
cookie,
{ gundamId, gdId, appJs, renderList },
guard
) {
const jsText = await fetch(appJs).then((res) => res.text())
const data =
resolveRedMod(jsText, renderList) ??
resolveRedMod(jsText, await getRenderList(cookie, gdId, guard))

if (!data) {
throw new Error('天天神券 Payload 生成失败')
throw new Error(`[${gundamId}] Gundam Payload 生成失败`)
}

return {
Expand All @@ -38,7 +53,8 @@ async function getPayload(gundamId, appJs, guard) {
platform: 3,
couponAllConfigIdOrderString: data.expandCouponIds.keys.join(','),
couponConfigIdOrderCommaString: data.priorityCouponIds.keys.join(','),
gundamId: gundamId,
// 这里取 number 类型的 gdId
gundamId: gdId,
instanceId: data.instanceID,
h5Fingerprint: '',
rubikCouponKey: data.cubeToken || '',
Expand Down Expand Up @@ -77,8 +93,8 @@ function formatCoupons(coupons, actName) {

async function grabCoupon(cookie, gundamId, guard) {
const actUrl = getActUrl(gundamId)
const { actName, appJs, gdId } = await getTemplateData(cookie, gundamId)
const payload = await getPayload(gdId, appJs, guard)
const tmplData = await getTemplateData(cookie, gundamId)
const payload = await getPayload(cookie, tmplData, guard)
const res = await fetch.post(
'https://mediacps.meituan.com/gundam/gundamGrabV4',
payload,
Expand All @@ -93,12 +109,12 @@ async function grabCoupon(cookie, gundamId, guard) {
)

if (res.code == 0) {
return formatCoupons(res.data.coupons, actName)
return formatCoupons(res.data.coupons, tmplData.actName)
}

const apiInfo = {
api: 'gundamGrabV4',
name: actName,
name: tmplData.actName,
msg: res.msg || res.message
}

Expand Down
41 changes: 18 additions & 23 deletions src/coupons/index.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,36 @@
import fetch from '../fetch.js'
import ShadowGuard from '../shadow/index.js'
import { createMTCookie, getUserInfo } from '../user.js'
import { mainActConf, wxfwhActConf, ECODE } from './const.js'
import mainAct from './gundamGrab.js'
import wxfwhAct from './wxfwh.js'
import { mainActConf, gundamActConfs, wxfwhActConfs, ECODE } from './const.js'
import gundam from './gundam.js'
import wxfwh from './wxfwh.js'

async function runTask(cookie, guard) {
try {
// 优先检测登录状态
const userInfo = await getUserInfo(cookie)
const allResults = []

for (const conf of mainActConf) {
// 主活动,失败时向外抛出异常
const result = await mainAct.grabCoupon(cookie, conf.gid, guard)
// 主活动,失败时向外抛出异常
const results = await gundam.grabCoupon(cookie, mainActConf.gid, guard)

allResults.push(...result)
}

for (const conf of wxfwhActConf) {
try {
// 微信服务号活动,失败时忽略
const wxResult = await wxfwhAct.grabCoupon(cookie, conf.gid, guard)
// 次要活动,并行执行提升效率
const asyncResults = await Promise.all([
...gundamActConfs.map((conf) =>
gundam.grabCoupon(cookie, conf.gid, guard).catch(() => [])
),
// 微信服务号活动
...wxfwhActConfs.map((conf) =>
wxfwh.grabCoupon(cookie, conf.gid, guard).catch(() => [])
)
])

allResults.push(...wxResult)
} catch (e) {
// ignore
}
}
results.push(...asyncResults.flat())

return {
code: ECODE.SUCC,
data: {
userInfo,
coupons: allResults
coupons: results
},
msg: '成功'
}
Expand Down Expand Up @@ -88,9 +85,7 @@ async function getCoupons(token, { maxRetry = 0, httpProxy }) {
const cookieJar = createMTCookie(token)

// 复用 guard
const guard = await new ShadowGuard().init(
mainAct.getActUrl(mainActConf[0].gid)
)
const guard = await new ShadowGuard().init(gundam.getActUrl(mainActConf.gid))

async function main(retryTimes = 0) {
const result = await runTask(cookieJar, guard)
Expand Down
24 changes: 8 additions & 16 deletions src/coupons/wxfwh.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ async function getPayloadTabs(cookie, viewId) {

async function getPayload(
cookie,
{ gdId, pageId, renderList, appJs, fingerprint }
{ gundamId, gdId, pageId, renderList, appJs },
guard
) {
const jsText = await fetch(appJs).then((res) => res.text())
let data = null
Expand All @@ -90,7 +91,7 @@ async function getPayload(
}

if (!data) {
throw new Error('服务号 Payload 生成失败')
throw new Error(`[${gundamId}] wxfwh Payload 生成失败`)
}

const tabs = await getPayloadTabs(cookie, data.viewId)
Expand All @@ -105,23 +106,14 @@ async function getPayload(
gdId: gdId,
pageId: pageId,
instanceId: data.instanceId,
mtFingerprint: fingerprint
mtFingerprint: guard.fingerprint
}
}

async function grabCoupon(cookie, gundamId, guard) {
const actUrl = getActUrl(gundamId)
const { actName, gdId, pageId, renderList, appJs } = await getTemplateData(
cookie,
gundamId
)
const payload = await getPayload(cookie, {
gdId,
pageId,
renderList,
appJs,
fingerprint: guard.fingerprint
})
const tmplData = await getTemplateData(cookie, gundamId)
const payload = await getPayload(cookie, tmplData, guard)

if (!payload.tabs.length) {
return []
Expand Down Expand Up @@ -149,12 +141,12 @@ async function grabCoupon(cookie, gundamId, guard) {
)

if (res.code == 0) {
return formatCoupons(res.data.couponList, actName)
return formatCoupons(res.data.couponList, tmplData.actName)
}

const apiInfo = {
api: 'generalcoupon/fetch',
name: actName,
name: tmplData.actName,
msg: res.msg || res.message
}

Expand Down
4 changes: 3 additions & 1 deletion src/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ async function getTemplateData(cookie, gundamId) {
const globalData = JSON.parse(matchGlobal[1])

return {
gundamId,
gdId: globalData.gdId,
actName: globalData.pageInfo.title,
appJs: appJs,
Expand All @@ -45,7 +46,7 @@ function formatRendeInfo(renderInfo) {
}

// 通过接口获取真实的渲染列表
async function getRenderList(gdNumId, guard) {
async function getRenderList(cookie, gdNumId, guard) {
let data

try {
Expand All @@ -58,6 +59,7 @@ async function getRenderList(gdNumId, guard) {
gdId: gdNumId,
tenant: 'gundam'
},
cookie,
guard
}
)
Expand Down
6 changes: 3 additions & 3 deletions test/coupons.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { createMTCookie, parseToken } from '../src/user.js'
import { getCoupons, ECODE } from '../src/coupons/index.js'
import wxfwhGrab from '../src/coupons/wxfwh.js'

const tokens = parseToken(process.env.TOKEN)
const cookie = createMTCookie(tokens[0].token)

test('Test Coupons', async () => {
const tokens = parseToken(process.env.TOKEN)
const res = await getCoupons(tokens[0].token, {
// proxy: 'http://127.0.0.1:8887'
})
Expand All @@ -22,8 +24,6 @@ test('Test Token Error', async () => {
})

test('Test Result Format', async () => {
const tokens = parseToken(process.env.TOKEN)
const cookie = createMTCookie(tokens[0].token)
const res = await wxfwhGrab.getCouponList(cookie, 'I5r2SYd5kTN1l1AkMhwCNA')

expect(res).toBeTruthy()
Expand Down
37 changes: 13 additions & 24 deletions test/payload.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { getTemplateData } from '../src/template.js'
import ShadowGuard from '../src/shadow/index.js'
import mainAct from '../src/coupons/gundamGrab.js'
import mainAct from '../src/coupons/gundam.js'
import wxfwhAct from '../src/coupons/wxfwh.js'
import { mainActConf, wxfwhActConf } from '../src/coupons/const.js'
import { mainActConf, wxfwhActConfs } from '../src/coupons/const.js'
import { createMTCookie, parseToken } from '../src/user.js'

const guard = new ShadowGuard()
const tokens = parseToken(process.env.TOKEN)
const cookie = createMTCookie(tokens[0].token)

beforeAll(() => guard.init(mainAct.getActUrl(mainActConf[0].gid)))
beforeAll(() => guard.init(mainAct.getActUrl(mainActConf.gid)))

test('Test Main Payload', async () => {
const { gdId, appJs } = await getTemplateData(null, mainActConf[0].gid)
const payload = await mainAct.getPayload(gdId, appJs, guard)
const tmplData = await getTemplateData(null, mainActConf.gid)
const payload = await mainAct.getPayload(cookie, tmplData, guard)

return expect(payload).toMatchObject({
actualLatitude: 0,
Expand All @@ -20,7 +22,7 @@ test('Test Main Payload', async () => {
platform: 3,
couponConfigIdOrderCommaString: expect.any(String),
couponAllConfigIdOrderString: expect.any(String),
gundamId: gdId,
gundamId: tmplData.gdId,
needTj: expect.any(Boolean),
instanceId: expect.any(String),
h5Fingerprint: '',
Expand All @@ -29,27 +31,16 @@ test('Test Main Payload', async () => {
})

test('Test Wxfwh Payload', async () => {
const tokens = parseToken(process.env.TOKEN)
const cookie = createMTCookie(tokens[0].token)
const { gdId, pageId, renderList, appJs } = await getTemplateData(
null,
wxfwhActConf[1].gid
)
const payload = await wxfwhAct.getPayload(cookie, {
gdId,
pageId,
renderList,
appJs,
fingerprint: guard.fingerprint
})
const tmplData = await getTemplateData(null, wxfwhActConfs[1].gid)
const payload = await wxfwhAct.getPayload(cookie, tmplData, guard)

return expect(payload).toMatchObject({
ctype: 'wm_wxapp',
fpPlatform: 13,
wxOpenId: '',
appVersion: '',
gdId: gdId,
pageId: pageId,
gdId: tmplData.gdId,
pageId: tmplData.pageId,
tabs: expect.any(Array),
activityViewId: expect.any(String),
instanceId: expect.any(String),
Expand All @@ -58,9 +49,7 @@ test('Test Wxfwh Payload', async () => {
})

test('Test Wxfwh grab', async () => {
const tokens = parseToken(process.env.TOKEN)
const cookie = createMTCookie(tokens[0].token)
const res = await wxfwhAct.grabCoupon(cookie, wxfwhActConf[1].gid, guard)
const res = await wxfwhAct.grabCoupon(cookie, wxfwhActConfs[1].gid, guard)

return expect(res).toBeTruthy()
})
4 changes: 2 additions & 2 deletions test/shadow.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import ShadowGuard from '../src/shadow/index.js'
import grab from '../src/coupons/gundamGrab.js'
import mainGrab from '../src/coupons/gundam.js'
import { mainActConf } from '../src/coupons/const.js'

const guard = new ShadowGuard({
dfpId: '8v0111yz74185w7deu38vz71222u80w981zvylws4779123469xu4399'
})

beforeAll(() => guard.init(grab.getActUrl(mainActConf[0].gid)))
beforeAll(() => guard.init(mainGrab.getActUrl(mainActConf.gid)))

test('Test Generate Session', () =>
expect(guard.meta.sessionId).toHaveLength(32))
Expand Down
Loading

0 comments on commit 0bc3c88

Please sign in to comment.