LINE WORKS Advent Calendar 5日目!どうぞよろしくお願いします♪
前々からお知らせされていたのですが、今年の 9月に一部の古いバージョンの API が使用できなくなりました。
それでふと、前に自分が書いた記事を見てみたら、やっぱりというか古いバージョンでの記事でした。
API を使って LINE WORKS BOT を登録する
まぁ、記事を修正するよりは、Advent Calendar の時期ですし?
新しく記事を書きなおそうと思った次第なのです。('ω')
だって、2年まえの私は async
await
を使えなくて、非同期処理は全部 Callback
でやってたんですよ( ゚Д゚)
おまけに 文字列内の変数は全部 +
で結合してましたし。。。
あぁ、恥ずかしい。。。(ノωノ)
前置きが長くなりました。
そろそろ、API で BOT を登録していきましょう。
LINE WORKS API で BOT を登録するためには
LINE WORKS BOT を登録するためには複数の API を使用します。
旧バージョンの API との比較ですが、新バージョンでは Callback URL の登録がトーク Bot のテナント登録 API でできるようになっています。
なので手順は一個減っているのですが、API Access Token を取得する手順を追加しますので、やっぱり 4 STEP ですね。
事前準備
-
LINE WORKS 認証情報を 【LINE WORKS】API 認証情報の取得方法まとめ を参考に取得しておきます。
-
このプログラムコードではモジュール2つを使っています。予めインストールしておきます。
npm install request-promise --save
npm install jsonwebtoken --save
Node.js で Bot を登録するコード
では、実際のコードです。
// LINE WORKS 認証情報
const CONSTS = {
"DOMAIN_ID": "xxxxxxxx";
"API_ID": "xxxxxxxxxxx";
"CONSUMER_KEY": "xxxxxxxxxxxxxxxxxx";
"SERVER_ID": "xxxxxxxxxxxxxxxxxxxxxxxxxx";
"PRIVATEKEY": "-----BEGIN PRIVATE KEY-----\nxxxxxxxxxx\n-----END PRIVATE KEY-----";
"MANAGER_ID": "xxxx@yyyy-zzzz";
}
// module
const request = require("request-promise");
// main
main();
async function main() {
const token = await getServerToken();
const botNo = await addTalkBot(token);
const result = await regTalkBot(token, botNo);
if(result) sendMsg(token, botNo);
}
/**
* LINE WORKS の Server Token を取得
* @return {Promise object} Server Token
*/
async function getServerToken() {
const jwt = require("jsonwebtoken");
const iss = CONSTS.SERVER_ID;
const iat = Math.floor(Date.now() / 1000);
const exp = iat + 60 * 60; // 有効期間を 1時間に設定
const cert = CONSTS.PRIVATEKEY;
const options = {
method: "POST",
url: `https://auth.worksmobile.com/b/${CONSTS.API_ID}/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: jwt.sign({ iss: iss, iat: iat, exp: exp }, cert, { algorithm: "RS256" }),
}
};
return new Promise((resolve, reject) => {
request(options).then((res) => {
const result = JSON.parse(res);
if (result.message) throw "Could not get token";
resolve(result);
}).catch((error) => {
console.log(`Auth Error: ${error}`);
reject(error);
});
});
}
/**
* LINE WORKS にトーク Bot を登録
* @param {object} token LINE WORKS の Server Token
* @return {Promise object} 登録した Bot の botNo
*/
async function addTalkBot(token){
const options = {
method: "POST",
url: `https://apis.worksmobile.com/r/${CONSTS.API_ID}/message/v1/bot`,
headers: {
"Content-type": "application/json",
"consumerKey": CONSTS.CONSUMER_KEY,
"Authorization": `${token.token_type} ${token.access_token}`
},
json: {
"name": "test bot",
"photoUrl": "https://developers.worksmobile.com/favicon.png",
"description": "qiita sample bot",
"managers": [CONSTS.MANAGER_ID]
}
};
return new Promise((resolve, reject) => {
request(options).then((res) => {
if (res.errorMessage) throw `Could not add TalkBot:${JSON.stringify(res)}`;
resolve(res.botNo);
}).catch((error) => {
console.log(`Add TalkBot Error: ${error}`);
reject(error);
});
});
}
/**
* Domain にトーク Bot を登録して公開する
* @param {object} token LINE WORKS の Server Token
* @param {string} botNo Domain に登録する Bot の botNo
* @return {Promise object} 登録が成功したかどうかの真偽値
*/
async function regTalkBot(token, botNo){
const options = {
method: "POST",
url: `https://apis.worksmobile.com/r/${CONSTS.API_ID}/message/v1/bot/${botNo}/domain/${CONSTS.DOMAIN_ID}`,
headers: {
"Content-type": "application/json",
"consumerKey": CONSTS.CONSUMER_KEY,
"Authorization": `${token.token_type} ${token.access_token}`
}
};
return new Promise((resolve, reject) => {
request(options).then((res) => {
if (res.errorMessage) throw `Could not reg TalkBot:${JSON.stringify(res)}`;
resolve(Boolean("true"));
}).catch((error) => {
console.log(`Add TalkBot Error: ${error}`);
reject(Boolean("false"));
});
});
}
/**
* 管理者に登録完了メッセージを送信
* @param {object} token LINE WORKS の Server Token
* @param {string} botNo メッセージを送信する Bot の botNo
*/
async function sendMsg(token, botNo){
const options = {
method: "POST",
url: `https://apis.worksmobile.com/r/${CONSTS.API_ID}/message/v1/bot/${botNo}/message/push`,
headers: {
"Content-type": "application/json",
"consumerKey": CONSTS.CONSUMER_KEY,
"Authorization": `${token.token_type} ${token.access_token}`
},
json: {
"accountId": CONSTS.MANAGER_ID,
"content": {
"type": "text",
"text": "Bot 登録が完了しました!"
}
}
};
return new Promise((resolve, reject) => {
request(options).then((res) => {
if (res.errorMessage) throw `Could not send message:${JSON.stringify(res)}`;
resolve("success");
}).catch((error) => {
console.log(`send message Error: ${error}`);
reject("error");
});
});
}
コードの解説
少しだけ解説を。
全体としては前回よりかなり長いコードになりましたが、可読性は上がったと思います。
また、Javadoc コメントの記述方法も勉強して、なるべく書くようにしています。
プログラムの内容ですが、前述の 4 STEP をそれぞれ関数にしました。
async
await
を使用して非同期処理をしています。
それぞれの機能を独立させ、メインプログラムで呼び出すようにしました。
- API Access Token の取得 -
function getServerToken()
- トーク Bot のテナント登録 -
function addTalkBot(token)
- トーク Bot のドメイン登録 -
function regTalkBot(token, botNo)
- トーク Bot からメッセージ送信 -
function sendMsg(token, botNo)
1 の API Access Token の取得はよく使うので、別のプログラム作るときにも応用が効きます。
実際、前に書いた記事からコピペしてきただけですしね( ゚Д゚)
おわりに
ここまでお付き合いいただきありがとうございました。
前の記事を書いてから約1年半。
昔の内容と比べるとずいぶん成長したなぁ、と少し自分を誇らしく思っています。
まだまだ知らないこともたくさんありますし、覚えた知識も使わないと忘れます。
技術は日々進歩しますし、新しいサービスや機能も増えていきます。
明日も少しマシな自分を目指して、これからも頑張っていきたいです!
ではまた!(^^)/