今回の内容
2021年12月1日、API廃止の関係で動かなくなるかもしれないので、下記のリンクにしたがって修正してください。
こちらのブログでも修正しておきます。
現在、トライアルでLINE WORKSのトークBotを作成しています。
プロジェクトはNode.js + Herokuで進めています。
トークBotを作成する際にトークBotのメッセージを受信し、callbackするサーバーに秘密鍵の情報を登録しなければいけないのですが、LINE WORKSの公式ドキュメントに掲載されている認証キーのファイルは下図のような感になっているのに対して
私がダウンロードしているxxxxxx.keyファイルは
—–BEGIN PRIVATE KEY—–
aaa
bbb
ccc
—–END PRIVATE KEY—–
のようになっている。
あれ、なんか違う。
—–BEGIN RSA PRIVATE KEY—–
aaa
—–END RSA PRIVATE KEY—–↓私のファイル
—–BEGIN PRIVATE KEY—–
aaa
—–END PRIVATE KEY—–
ということで調べてみるとやはり、ダウンロードした.keyファイルのエンコード方式が違う、もともとはおそらく、ただの平文だったor Der方式だった??ようでPEMでエンコードできるように、下記コマンドを実行して、環境変数に登録したところ上手く動くようになりました。
openssl rsa -in <my file name>.key -out <my file name>.key -outform pem
opensslコマンドについての簡易なメモ
openssl rsa
コマンドはRSAの秘密鍵を使った処理を行うもの。
Herokuの環境変数への登録
今回は秘密鍵の内容をHerokuの環境変数へ登録して利用したいため下記のコマンドで登録しようとしたのですが、改行やスペースがあると上手く扱えないようです。
heroku config:set =""
そのため今回はいさぎよく諦めてHerokuの画面から登録しました。
Herokuのsettings > config varのところで直接書き込みしました。
今回のサンプル貼っておきます。
"use strict"; // モジュールインポート const express = require("express"); const server = express(); const bodyParser = require("body-parser"); const jwt = require('jsonwebtoken'); const https = require("https"); const request = require("request"); const qs = require("querystring"); //変数 const APIID = process.env.APIID; const SERVERID = process.env.SERVERID; const CONSUMERKEY = process.env.CONSUMERKEY; const PRIVATEKEY = process.env.PRIVATEKEY; const BOTNO = process.env.BOTNO; server.use(bodyParser.json()); // Webアプリケーション起動 server.listen(process.env.PORT || 3000); // サーバー起動確認 server.get('/', (req, res) => { res.send('Hello World!'); }); // Botからメッセージに応答 server.post('/callback', (req, res) => { res.sendStatus(200); const message = req.body.content.text; const roomId = req.body.source.roomId; const accountId = req.body.source.accountId; // ここが認証しているところ // ここに詳しく書いてある // https://developers.worksmobile.com/jp/document/1002002?lang=ja getJWT((jwttoken) => { getServerToken(jwttoken, (newtoken) => { sendMessage(newtoken, accountId, message); }); }); }); //1. サーバーAPI用JWT取得 function getJWT(callback){ const iss = SERVERID; const iat = Math.floor(Date.now() / 1000); const exp = iat + (60 * 60); //JWTの有効期間は1時間 const cert = PRIVATEKEY; const token = []; const jwttoken = jwt.sign({"iss":iss, "iat":iat, "exp":exp}, cert, {algorithm:"RS256"}, (err, jwttoken) => { if (!err) { callback(jwttoken); } else { console.log(err); } }); } //2. サーバートークンの取得 function getServerToken(jwttoken, callback) { const postdata = { url: 'https://authapi.worksmobile.com/b/' + APIID + '/server/token', headers : { 'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8', }, form: { "grant_type" : encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer"), "assertion" : jwttoken } }; request.post(postdata, (error, response, body) => { if (error) { console.log(err); callback(err); } else { const jsonobj = JSON.parse(body); const AccessToken = jsonobj.access_token; callback(AccessToken); } }); } //sendMessageを利用したメッセージ送信 function sendMessage(token, accountId, message) { const postdata = { //2021年12月1日修正 url:'https://apis.worksmobile.com/r/' + APID + '/message/v1/' + BOTNO + '/message/push’ /*ここから url: 'https://apis.worksmobile.com/' + APIID + '/message/sendMessage/v2', ここまで削除 廃止APIのため*/ headers : { 'Content-Type' : 'application/json;charset=UTF-8', 'consumerKey' : CONSUMERKEY, 'Authorization' : "Bearer " + token }, json: { "botNo" : Number(BOTNO), "accountId" : accountId, "content" : { "type" : "text", "text" : message } } }; request.post(postdata, (error, response, body) => { if (error) { console.log(error); } console.log(body); }); }
サンプルコードを使ってチャットbotがコールバックを返してくれました。コピーしただけですが、大変参考になりました。
nori.3dogsさん
コメントありがとうございます。
今日ですが、このサンプルに使っているコードですと、API廃止の関係で明日から利用できなくなってしまうかもしれません。
https://developers.worksmobile.com/jp/document/10016001?lang=ja
リクエストURLを下記のリンクのもの差し替えいただくと問題なく動くと思います。
どうぞ利用してくだい!
https://developers.worksmobile.com/jp/document/100500801/v2?lang=ja
“`
https://apis.worksmobile.com/r/{API ID}/message/v1/bot/{botNo}/message/push
“`
※URL書き換えるだけで動きます。