一般の WeChat ユーザーが公開アカウントにメッセージを送信すると、WeChat サーバーは、開発者が入力した URL にメッセージの XML データ パケットを POST します。
2.1 受信共通メッセージデータ形式
XMLの構造は基本的に固定されており、メッセージタイプが異なると若干異なります。
ユーザーがテキストメッセージを送信する場合、WeChatパブリックアカウントが受信する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>
ユーザーが画像メッセージを送信する場合、WeChatパブリックアカウントが受信する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>
その他のメッセージタイプ 構造については、[WeChatパブリックプラットフォーム開発ドキュメント]を参照してください
POSTリクエストの処理については、koa2はパラメータの取得メソッドをカプセル化しておらず、ネイティブの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データパケットを受け入れる機能の実装は開始されていませんが、前のコードを修正しています。これは、実際の開発プロセスを示すためです。コードの作成は 1 ステップのプロセスではなく、優れたコードは変更するだけです。
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 WeChat パブリック アカウントを操作してメッセージ管理を実現する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。