#前提:
Bluemixアカウント持っている事
Juzzhubとつなげている事↓
https://www.ibm.com/developerworks/jp/cloud/library/cl-poseidon2-app/
LINE Botを作っていること
Node-redが使用可能な事
#中身
###設定ファイル修正
(設定ファイル修正は、JuzzHubでやればブラウザオンリーでカンタンですよ。)
functionGlobalContext: {
crypto: require( "crypto" )
process: process
},
http://stackoverflow.com/questions/37121402/how-to-get-user-defined-variables-in-node-red-app-in-bluemix
http://qiita.com/joeartsea/items/b5e8e14498f3098990c3
によると、bluemix-settings.jsのGlobalcontextに入れたものにアクセスするには、context.globalの下みれば良い。
HMACを使うためには、cryptoが必要です。
かつ、X-Line-Channel-Secretをソースコードにベタ書きするのが嫌なので環境変数に入れて使いたいので、processが必要です。(ここはベタ書き派な人は不要)
###環境変数の追加
ダッシュボードの環境変数画面で以下をそれぞれ追加。値はLINEから貰った内容を入れましょう。-(ハイフン)が入ると呼び出すときになんかダメだったのでハイフン抜きにしました。(まだこの辺は不慣れです)
XLineChannelID
XLineChannelSecret
XLineTrustedUserWithACL
###Function Node作成
http://dev.classmethod.jp/cloud/build-line-bot-api-using-lambda/
↑これ神!msg.payload
をそのままhmac.update
しようとしても結果が全然ちがった。多分データ取り出すときの微妙な話だろうと思って散々調べて、このサイトみて同じようにやったら動いた。ここでかなりハマった。
結果的に、以下の様なFunctionNodeを追加してmsg.validation
に入れた値とmsg.req.headers.x-line-channelsignature
の値をSwitchNodeとかで比較したらValidation出来ます。
const hmac = context.global.crypto.createHmac( 'sha256' , context.global.process.env.XLineChannelSecret );
hmac.update( Buffer(JSON.stringify(msg.payload), 'utf8') );
var calcResult = hmac.digest('base64');
msg.validation = calcResult;
以上です。
再現用のJSONを貼っておきます。
[{"id":"abedd440.742ec","type":"http in","z":"7e7669e.258d498","name":"Callback","url":"/callback","method":"post","swaggerDoc":"","x":75,"y":112,"wires":[["943f3bcb.08ff6","67c4fc9.4bf7704"]]},{"id":"943f3bcb.08ff6","type":"debug","z":"7e7669e.258d498","name":"","active":true,"console":"false","complete":"req.headers.x-line-channelsignature","x":389,"y":165,"wires":[]},{"id":"67c4fc9.4bf7704","type":"function","z":"7e7669e.258d498","name":"validation","func":"const hmac = context.global.crypto.createHmac( 'sha256' , context.global.process.env.XLineChannelSecret );\nhmac.update( Buffer(JSON.stringify(msg.payload), 'utf8') );\nvar calcResult = hmac.digest('base64');\n\nmsg.validation = calcResult;\n\nreturn msg;","outputs":1,"noerr":0,"x":260,"y":240,"wires":[["9175c10b.130798"]]},{"id":"9175c10b.130798","type":"switch","z":"7e7669e.258d498","name":"validation switch","property":"validation","propertyType":"msg","rules":[{"t":"eq","v":"req.headers.x-line-channelsignature","vt":"msg"}],"checkall":"true","outputs":1,"x":420,"y":240,"wires":[["a532532b.79b0e"]]},{"id":"a532532b.79b0e","type":"debug","z":"7e7669e.258d498","name":"","active":true,"console":"false","complete":"validation","x":612,"y":245,"wires":[]}]
##その他
http://qiita.com/yoichiro6642/items/6d4c7309210af20a5c8f
こちらに書いてある、まずQueueに入れるってのも(パフォーマンス検証したわけじゃないですが)結構カンタンに実装出来たので別途記事を上げます。