首頁  >  文章  >  web前端  >  如何操作Koa2微信公眾號實現訊息管理

如何操作Koa2微信公眾號實現訊息管理

php中世界最好的语言
php中世界最好的语言原創
2018-05-29 11:15:192387瀏覽

接收訊息

當一般微信用戶向公眾帳號發送訊息時,微信伺服器將POST訊息的XML封包到開發者填寫的URL上。

2.1 接收普通訊息資料格式

XML的結構基本上固定,不同的訊息類型略有不同。

用戶傳送文字訊息時,微信公眾帳號接收到的XML資料格式如下所示:

<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
 <CreateTime>createTime</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[this is a test]]></Content>
 <MsgId>1234567890123456</MsgId>
</xml>

使用者傳送圖片訊息時,微信公眾帳號接收到的XML資料格式如下所示:

<xml> 
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
 <CreateTime>1348831860</CreateTime> 
 <MsgType><![CDATA[image]]></MsgType> 
 <PicUrl><![CDATA[this is a url]]></PicUrl>
 <MediaId><![CDATA[media_id]]></MediaId> 
 <MsgId>1234567890123456</MsgId>
</xml>

其他訊息訊息類型的結構請查閱【微信公眾平台開發文件】

#對於POST請求的處理,koa2沒有封裝取得參數的方法,需要透過自己解析上下文context中的原生node.js請求物件request。我們將用到row-body這個模組來拿到資料。

2.2 先來優化之前的程式碼

這一節的程式碼緊接著上一屆實現的程式碼,在上一屆的基礎上輕微改動了下。

'use strict'
const Koa = require('koa')
const app = new Koa()
const crypto = require('crypto')
// 将配置文件独立到config.js
const config = require('./config')
app.use(async ctx => {
 // GET 验证服务器
 if (ctx.method === 'GET') {
  const { signature, timestamp, nonce, echostr } = ctx.query
  const TOKEN = config.wechat.token
  let hash = crypto.createHash('sha1')
  const arr = [TOKEN, timestamp, nonce].sort()
  hash.update(arr.join(''))
  const shasum = hash.digest('hex')
  if (shasum === signature) {
   return ctx.body = echostr
  }
  ctx.status = 401
  ctx.body = 'Invalid signature'
 } else if (ctx.method === 'POST') { // POST接收数据
  // TODO
 }
});
app.listen(7001);

這兒我們在只在GET中驗證了簽名值是否合法,實際上我們在POST中也應該驗證簽名。

將簽章驗證寫成一個函數

function getSignature (timestamp, nonce, token) {
 let hash = crypto.createHash('sha1')
 const arr = [token, timestamp, nonce].sort()
 hash.update(arr.join(''))
 return hash.digest('hex')
}

優化程式碼,再POST中也加入驗證

...
app.use(async ctx => {
 const { signature, timestamp, nonce, echostr } = ctx.query
 const TOKEN = config.wechat.token
 if (ctx.method === 'GET') {
  if (signature === getSignature(timestamp, nonce, TOKEN)) {
   return ctx.body = echostr
  }
  ctx.status = 401
  ctx.body = 'Invalid signature'
 }else if (ctx.method === 'POST') {
  if (signature !== getSignature(timestamp, nonce, TOKEN)) {
   ctx.status = 401
   return ctx.body = 'Invalid signature'
  }
  // TODO
 }
});
...

到這兒我們都沒有開始實作接受XML資料包的功能,而是在修改之前的程式碼。這是為了示範在實際開發中的過程,寫任何程式碼都不是一步到位的,好的程式碼都是改出來的。

2.3 接收公眾號普通訊息的XML封包

#現在開始進入本節的重點,接受XML封包並轉為JSON

$ npm install raw-body --save
...
const getRawBody = require('raw-body')
...
// TODO
// 取原始数据
const xml = await getRawBody(ctx.req, {
 length: ctx.request.length,
 limit: '1mb',
 encoding: ctx.request.charset || 'utf-8'
});
console.log(xml)
return ctx.body = 'success' // 直接回复success,微信服务器不会对此作任何处理

給你的測試號發送文字訊息,你可以在命令列看見列印如下資料

<xml>
 <ToUserName><![CDATA[gh_9d2d49e7e006]]></ToUserName>
 <FromUserName><![CDATA[oBp2T0wK8lM4vIkmMTJfFpk6Owlo]]></FromUserName>
 <CreateTime>1516940059</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[JavaScript之禅]]></Content>
 <MsgId>6515207943908059832</MsgId>
</xml>

恭喜,到此你已經可以接收到XML資料了。

以上是如何操作Koa2微信公眾號實現訊息管理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn