2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Node.js × LINE WORKS API】API で BOT を登録する

Last updated at Posted at 2020-12-04

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 ですね。

  1. API Access Token の取得
  2. トーク Bot のテナント登録
  3. トーク Bot のドメイン登録
  4. トーク Bot からメッセージ送信

事前準備

npm install request-promise --save
npm install jsonwebtoken --save

Node.js で Bot を登録するコード

では、実際のコードです。

main.js
// 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 を使用して非同期処理をしています。
それぞれの機能を独立させ、メインプログラムで呼び出すようにしました。

  1. API Access Token の取得 - function getServerToken()
  2. トーク Bot のテナント登録 - function addTalkBot(token)
  3. トーク Bot のドメイン登録 - function regTalkBot(token, botNo)
  4. トーク Bot からメッセージ送信 - function sendMsg(token, botNo)

1 の API Access Token の取得はよく使うので、別のプログラム作るときにも応用が効きます。
実際、前に書いた記事からコピペしてきただけですしね( ゚Д゚)

おわりに

ここまでお付き合いいただきありがとうございました。

前の記事を書いてから約1年半。
昔の内容と比べるとずいぶん成長したなぁ、と少し自分を誇らしく思っています。

まだまだ知らないこともたくさんありますし、覚えた知識も使わないと忘れます。
技術は日々進歩しますし、新しいサービスや機能も増えていきます。

明日も少しマシな自分を目指して、これからも頑張っていきたいです!

ではまた!(^^)/

参考にさせていただきましたm(_ _)m

LINE WORKS Developers

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?