5
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でByteDance製ビジネスアプリLarkのBotを作る

Last updated at Posted at 2020-10-15

#Larkってなに
Larkとは、シンガポールに本社を置くLark Technologiesが開発するアプリでチャット、ビデオ、カレンダー、スプレッドシート、ドキュメントなど全部入りのビジネスソフトと言っていいでしょう

こちらの企業はTikTokでおなじみのバイトダンス(字節跳動)の子会社ということで、同社は海外向けやエンタープライズ向けの製品に力を入れたい意向があるそうです
G SuiteやOffice、Slackなどの競合に位置する気概のようですが、そういうバックグラウンドはいちエンジニアの端くれたる僕には関係なく、ともかく僕のチームで採用されていています
img1.png
日本語公式サイトより

できることが多彩で正直使い切れてないのですが、LarkではAppという形で外部と連携した機能を使えるようです。

Appにはチーム内で使用するCustom Appと、Larkユーザー全体に公開できるPublic Appとがあり、それぞれにまたGadget、Web page、Botという区分があります。よくわからない。
img2.png
img3.png
Lark Developer - Open Platform Overview

#今回つくるもの
その中で今回は、特定のチャットにメッセージを送る機能を用いたいと思うのでCustom AppのBotにあるメッセージ機能を使います

どこかの環境にBotサーバーを設置し、それを呼び出すことでLarkのチャットにメッセージが送られるという単純な仕組みにしたいと思います。

メッセージを受け取って返答したり、そのほかLark内のイベントに応じたアクションなどBotの機能は数多くありそうですが、今回は単純な送信のみに対応したいと思います。

実行環境はGoogleのCloud Functions上ですが、Node.jsを用いるのでGCEやAWSのEC2, Lambdaなど他の環境でも参考にできると思います。

サーバー自体のリクエスト処理などは今回の範疇外とさせていただきます。上記の通り環境にもよりますし、ただでさえ冗長なのと、何より初めてQiitaを書く僕が限界です。
※一応こちらのページにPythonでの完全なサンプルがありますが説明等はなく、コメントも中国語ですので自信のある方はお使いください。ほんとは解説したい。

#Lark botの設定
公式ドキュメントにしたがって進めます。サンプルやチュートリアルではないのでサーバーなどの話は載っていません。
img4.png

4つのプロセスに分かれていますが初めの2つだけで今回は実装できます

####AppとBotの設定

Create a Bot in LarkではLarkの開発者向けサイトからAppを追加し、Botを設定する手順が記載されています。直接コーディングなどはしませんが大まかに解説します。

See Create a custom app to Create an app for your business.

とのことなのでそこの解説です。公式のガイドに従えば特に支障なくすすめます。

Lark Developerの各ページから右上のMy Appsに移動し、Create an Appから必要な項目を入力してCustom Appを追加します。

それからApp Capabilityを有効化する必要があるので先ほど追加したAppの詳細を表示し、FeaturesからBotを有効化します。Permissionなどの指示もありますが不要です。

最後に、自分が使っているLarkからBotを見つけて使用するためにReleaseしてVersionを1度追加する必要があります。Releaseを行っても使用しているチームの外には見えないのでVersion Management & Releaseから適当に項目を入力してください。(チームの権限者から承認されるとチャットに追加できるようになります。)

####メッセージ送信の要件
Bot development processに戻りましょう。Appの設定ができたので次のSend messagesに進みます。

Step 1: Obtain the API access token
See Obtain access token.

Step 2: Invoke the message sending API
Send messages to users/group chats as an app. For the message API, see Send a message.

  • Send a private message: Send a message to a user within the app visibility range. A user must have an access visibility to that app.

  • Send group messages: Send messages within a group. The app needs to be in the corresponding group, see Using bots in groups.

といった形で2ステップ書かれています。Botからメッセージを送るにはアクセストークンが必要で、Step1ではその手法が書いてあります。Step2ではテキストメッセージの送信とその際に必要な情報が載っています。

先ほどのガイドに従ってもいいのですが、リンクのみの箇所が多いため直接リファレンスを参照することをお勧めします

まとめると

  1. Appの詳細からapp IDapp secretを取得する(初回のみ)
  2. IDとsecretでAPIを呼び出しAPIからchat_idを取得する(初回のみ)
  3. 同様に、tenant_access_tokenを取得する
  4. chat_idtenant_access_tokenと一緒にメッセージをリクエスト

といった流れで実装できます
1.と2.は変更されないのでbotサーバーの処理として行う必要はありません。ただし2.を呼び出すためには3.が必要なので前準備でもサーバーでも実行します。

ややこしいですが2.と3.を一度ターミナルのコマンドなどで済ませ、3.と4.をサーバーの処理として実装しましょう

#実装

####コマンドから認証情報を取得 (1.と3.の部分)
APIを呼び出すので任意のHTTPリクエストができるツールで構いませんがここではcurlを用います

リクエストを送信するのに必要な1.の情報は先ほどのMy Appsの該当アプリ設定ページから取得します
Credentials & Basic Infoの一番上にApp IDApp Secretが載っているので、下記コマンドの****に置き換えてください(この情報は後のサーバーコードでも使用します)

参考 : Reference > Getting Started > Authorization > Obtain tenant_access_token (internal apps)

$curl -XPOST -H 'Content-Type:application/json' -d '{"app_id":"*********","app_secret":"*********"}' https://open.larksuite.com/open-apis/auth/v3/tenant_access_token/internal/

これでtenant_access_tokenが入手できるので、次のコマンドにて使用します

####コマンドからchat_idを取得 (2.の部分)
同様にtenant_access_tokenを用いることでchat_idが入手できます

参考 : Reference > Bot > Group (Bot) > Obtain group list

$curl -H 'Authorization:Bearer *********'  https://open.larksuite.com/open-apis/chat/v4/list

整形しないと大変ですが以下の画像のようなレスポンスが得られます。

img10.png

この場合2つのチャットに参加しており、それぞれの情報が取得されています。チャット名はnameの部分に書かれていますが日本語の場合はコードに変換されているので探しにくいかもしれません。(背景は実際のLarkの画面です)

もし参加しているチャットが多い場合has_moreの部分がtrueになり、表示されません

ここで取得した、メッセージを送りたい目的のチャットのchat_idを後ほど使用します

#Nodeでメッセージを送信
やっと必要な情報が揃ったので実際のコードに移ります。メッセージ送信の要件にあった3.4.を書きましょう。

axiosを用いていますがこちらも好きなHTTPクライアントで構いません

まずコマンドでも行った3.の認証情報の取得を関数にまとめます。同様に、app_idapp_secretを用いてリクエストを送る処理です。単純なトークンを返すようにしましょう。

index.js
async function getTenantToken(app_id, app_secret) {
    const reqConf = {
        "conf": { "headers": { "Content-Type": "application/json" } },
        "data": {
            "app_id": app_id,
            "app_secret": app_secret,
        }
    }

    return await axios.post('https://open.larksuite.com/open-apis/auth/v3/tenant_access_token/internal/', reqConf.data, reqConf.conf)
        .then(function (response) {
            return response.data.tenant_access_token
        })
        .catch(function (error) {
            console.log(error);
        });
}

2.は先ほど用意したchat_idで良いので4.の処理です。こちらも情報さえあればPOSTリクエストを送るだけで可能なので簡単ですね。

index.js
async function sendMessageToLark(tenant_access_token, chat_id, message) {
    const reqConf = {
        "conf": {
            "headers": {
                "Content-Type": "application/json",
                "Authorization": "Bearer " + tenant_access_token,
            }
        },
        "data": {
            "chat_id": chat_id,
            "msg_type": "text",
            "content": {
                "text": message
            }
        }
    }

    await axios.post('https://open.larksuite.com/open-apis/message/v4/send/', reqConf.data, reqConf.conf)
        .then(function (response) {
            return
        })
        .catch(function (error) {
            console.log(error);
        });
}

上記の関数を実行すれば実際にLarkでメッセージを受け取れるでしょう。当然ですがIDやトークンなどセキュリティに関わる情報は直に記入せず環境変数などで秘匿化してください。

index.js
// さっきのchat_id
const chat_id = ************
const app_id = ************
const app_secret = ************
const message = "Lark Botからメッセージです"

getTenantToken(app_id, app_secret).then((r) => {
    sendMessageToLark(r, chat_id, message)
}).catch(e => console.log(e))

#まとめ
以上でLark Botから単純なメッセージの送信が実装できました。送信の部分は既存のチャットBotとあまり違いがなく、ほとんどがLarkの設定など固有の要素の理解が重要でしょうか。
実際ぼくも情報がない中で苦労したので少しでも参考になれば、と思います。

ドキュメントを見て分かる通り他にもLarkには多くの機能が存在します。チャットBotにしてもそもそもメッセージを受信するところから作れますし、Larkはそれだけでアプリ一つが成り立つようなかなり大規模なプラグインもできるようです。

まだまだ日本では途上にあるサービスなので、今後の動向を注視したいですね。

5
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
5
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?