前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >什么? 微信没有年度账单? 前端 nodejs 撸起来~ [接口实现]

什么? 微信没有年度账单? 前端 nodejs 撸起来~ [接口实现]

作者头像
ihoey
发布2020-01-21 15:29:25
8520
发布2020-01-21 15:29:25
举报
文章被收录于专栏:梦魇小栈梦魇小栈

最近逛掘金看见一片文章 非官方统计 2018 微信年度账单实现,作者利用调试微信获取到了 2018 年的所有消费明细,并根据类型进行分类统计,作文一个前端,便萌生了用 nodejs 实现一遍的想法,于是乎呢,就有了这篇文章了。

由于 @hibear 大佬是用 Java 实现的,并且自己又不会 Java,所以呢里面很多东西确实看不太懂,然后就根据核心代码撸吧。

好了,废话不多说,我们直接开始吧~

首先初始化一个项目吧,按自己的习惯,配置下需要的东西

大概配置完是这些文件

代码语言:javascript
复制
.editorconfig
.gitignore
config.js
init/
package.json
README.md
src/
util/
yarn.lock

然后我们来写个接口;

我们这里选 koa 框架吧,毕竟自己还是蛮喜欢的~

代码语言:javascript
复制
// Koa 框架
const Koa = require('koa')
// 实例化
const app = new Koa()
// 监听端口
app.listen(config.port)
console.log(`the server is start at port ${config.port}`)

然后我们来添加路由

代码语言:javascript
复制
// index.js
const Koa = require('koa')
const KoaRouter = require('koa-router')

const app = new Koa()
// 创建 router 实例对象
const router = new KoaRouter()

//注册路由
router.get('/', async ctx => {
  ctx.body = 'welcome~'
})

// 添加路由中间件
app.use(router.routes())

// 对请求进行一些限制处理
app.use(router.allowedMethods())

// 监听启动端口
app.listen(config.port)
console.log(`the server is start at port ${config.port}`)

完整入口文件

代码语言:javascript
复制
// index.js
const Koa = require('koa')
const KoaRouter = require('koa-router')
const bodyParser = require('koa-bodyparser')
const config = require('../config')

const app = new Koa()
// 创建 router 实例对象
const router = new KoaRouter()
// 账单获取核心逻辑
const wechatBill = require('./controllers/wechatBill')

// 配置ctx.body解析中间件
app.use(bodyParser())

//注册路由
router.get('/', async ctx => {
  ctx.body = 'welcome~'
})

router.post('/wechatBill', wechatBill)

// 添加路由中间件
app.use(router.routes())

// 对请求进行一些限制处理
app.use(router.allowedMethods())

// 监听启动端口
app.listen(config.port)
console.log(`the server is start at port ${config.port}`)

好了,路由写完了,我们来看核心逻辑怎么写,根据大佬的思路是模拟微信的请求,带上必要的参数就好了,这里我们使用最熟悉的 axios 吧。

由于代码太多这里就贴出核心的部分吧,完整版可以看下 github 的文件,请点击传送门-> 传送门

代码语言:javascript
复制
while (Loop) {

    if (lastResp.last_create_time < 1514736000) {
      wechatList.splice(wechatList.indexOf(wechat_id) >>> 0, 1)
      Loop = false
      console.log('任务处理完毕,2018全部数据已存入');
    }

    axios.request({
      url: `https://wx.tenpay.com/userroll/userrolllist`,
      method: 'get',
      headers: {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Accept-Language": "zh-CN,en-US;q=0.8",
        "Connection": "keep-alive",
        "Cookie": `userroll_encryption=${userroll_encryption}; userroll_pass_ticket=${userroll_pass_ticket}`,
        "Host": "wx.tenpay.com",
        "Q-Auth": AUTH,
        "Q-GUID": GUID,
        "Q-UA2": UA2,
        "Referer": "https://wx.tenpay.com/?classify_type=0",
        "User-Agent": "Mozilla/5.0 (Linux; Android 8.0; MIX 2 Build/OPR1.170623.027; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044408 Mobile Safari/537.36 MMWEBID/4508 MicroMessenger/7.0.1380(0x27000038) Process/tools NetType/WIFI Language/zh_CN",
        "X-DevTools-Emulate-Network-Conditions-Client-Id": ClientId,
        "X-Requested-With": "com.tencent.mm",
      },
      params: {
        classify_type: 0,
        count: PAGE_SIZE,
        exportkey,
        last_bill_id: lastResp.last_bill_id,
        last_bill_type: lastResp.last_bill_type,
        last_create_time: lastResp.last_create_time,
        last_trans_id: lastResp.last_trans_id,
        sort_type: 1,
        start_time: lastResp.start_time,
      }

    }).then((res) => {

      lastResp = res.data

      if (!lastResp || lastResp.ret_code != 0 || !lastResp.record) {
        console.log(lastResp);
        Loop = false
        ctx.body = {
          code: 2,
          res: lastResp.ret_msg || '任务请求失败'
        }
        throw new Error(`任务请求失败`)
      }

      ctx.body = {
        code: 0,
        res: '创建任务成功,正在获取账单中...'
      }

      const dataList = res.data.record.map(e => ({ wechat_id, ...e }))
      dataList.map(async e => {
        delete e.coupon
        const sql = `INSERT INTO orders(${Object.keys(e)}) VALUES (${JSON.stringify(Object.values(e))})`
        const data = await query(sql.replace(/\[|\]/g, ""))
        console.log(`存入成功`, data.insertId)
      })

    }).catch((err) => {
      console.log(err)
    });
    await sleep(1000)
  }

好了,具体的代码可以看下 github 的参考~ -> 传送门

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-01-182,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档