Boxへのボットの接続

Boxへのボットの接続

ここでは、Slackから送信されるイベントを処理し、Boxのユーザーやグループとの接続に必要なすべての情報を取得します。その機能をBoxの関数に関連付ける必要があります。

この手順では、直前の手順で説明した関数をいくつか拡張し、新しいBox機能を組み込みます。

  • Boxクライアントをインスタンス化する
  • BoxグループにBoxユーザーを追加する
  • BoxグループからBoxユーザーを削除する
  • グループ名からBoxグループIDを取得する
  • グループと共有するコンテンツを追加する

Boxクライアントのインスタンス化

Box APIを呼び出すには、最初にBoxクライアントを設定する必要があります。

process.jsで、先頭にある// INSTANTIATE BOX CLIENTコメントを次の内容に置き換えます。

const boxConfig = require("./boxConfig.json");
const sdk = box.getPreconfiguredInstance(boxConfig);
const client = sdk.getAppAuthClient("enterprise");

boxConfigの代入行では、手順2の最後でBoxアプリからダウンロードしたboxConfig.jsonファイルを使用します。上記のサンプルでは、ファイルをprocess.jsと同じフォルダに保存していることを前提としています。そうではない場合は、boxConfig.jsonファイルの場所を指すパスとファイル名に変更してください。

最後のclientの代入行では、APIコールに使用できるBoxクライアントオブジェクトを作成します。この時点では、その対象範囲は特定のユーザーではなく、アプリケーションのサービスアカウントに設定されています。

Application.javaで、processEventメソッド内の// INSTANTIATE BOX CLIENTコメントを次の内容に置き換えます。

this.fileReader = new FileReader("boxConfig.json");
this.boxConfig = BoxConfig.readFrom(fileReader);
this.boxAPI = BoxDeveloperEditionAPIConnection.getAppEnterpriseConnection(boxConfig);

boxConfigの代入行では、手順2の最後でBoxアプリからダウンロードしたboxConfig.jsonファイルを使用します。上記のサンプルでは、ファイルをJavaプロジェクトのルートに保存していることを前提としています。そうではない場合は、fileReaderの代入行のパスを、boxConfig.jsonファイルの場所を指すパスとファイル名に変更してください。

最後のboxAPIの代入行では、APIコールに使用できるBoxクライアントオブジェクトを作成します。この時点では、その対象範囲は特定のユーザーではなく、アプリケーションのサービスアカウントに設定されています。

前の手順が完了していません

最初に、手順1でお好みの言語/フレームワークを選択してください。

グループへのBoxユーザーの追加

グループにBoxユーザーを追加する関数を追加します。ボットがチャンネルに追加され、チャンネルのすべてのユーザーを含むBoxグループの作成が必要になった場合、またはその操作の後に1人のユーザーがチャンネルに参加した場合に、この関数によってそのタスクが実行されます。

addGroupUser関数を次の内容に置き換えます。

function addGroupUser(groupId, email) {
    client.enterprise.getUsers({ filter_term: email }).then((users) => {
        if (users.entries.length > 0) {
            const userId = users.entries[0].id;
            const groupRole = client.groups.userRoles.MEMBER;

            client.groups
                .addUser(groupId, userId, { role: groupRole })
                .then((membership) => {
                    if (membership.id) {
                        console.log(`Member added with membership ID: ${membership.id}`);
                    } else {
                        console.log(`Member not added`);
                    }
                })
                .catch(function (err) {
                    console.log(err.response.body);
                });
        } else {
            console.log("No Box user found to add to group");
        }
    });
}

addGroupUserメソッドを次の内容に置き換えます。

public void addGroupUser(String groupId, String userEmail) {
    Iterable<BoxUser.Info> users = BoxUser.getAllEnterpriseUsers(this.boxAPI, userEmail);

    for (BoxUser.Info user : users) {
        if (user.getLogin().toUpperCase().equals(userEmail.toUpperCase())) {
            try {
                BoxGroup group = new BoxGroup(boxAPI, groupId);
                BoxUser boxUser = new BoxUser(this.boxAPI, user.getID());
                BoxGroupMembership.Info groupMembershipInfo = group.addMembership(boxUser);
            } catch (Exception ex) {
                System.err.println("User already present");
            }
        }
    }
}

前の手順が完了していません

最初に、手順1でお好みの言語/フレームワークを選択してください。

メールアドレスを使用してSlackユーザーをBoxユーザーと照合しているため、最初に、Slackのプロフィールのメールアドレスを使用して一致するBoxユーザーを検索します。見つかると、そのユーザーをチャンネルのグループに追加するための呼び出しが行われます。このグループは、ボットが最初に追加されたときに作成されています。

Boxのユーザーを取得エンドポイントでは、ユーザーIDによるユーザー検索のみ許可されています。メールアドレスでユーザーを検索するには、会社ユーザーのリストを取得エンドポイントを使用し、filter_termオプションを検索対象のメールアドレスに設定します。

グループからのBoxユーザーの削除

Slackチャンネルから退出したユーザーや削除されたユーザーは、共有グループコンテンツにアクセスできなくなるようにBoxグループから削除することもできます。

removeGroupUser関数を次の内容に置き換えます。

function removeGroupUser(groupId, email) {
    client.groups.getMemberships(groupId).then(memberships => {
        for (let i = 0; i < memberships.entries.length; i++) {
            if (memberships.entries[i].user.login === email) {
                client.groups
                .removeMembership(memberships.entries[i].id)
                .then(() => {
                    console.log('Group user removed')
                });
                break;
            }
        }
    });
}

removeGroupUserメソッドを次の内容に置き換えます。

public void removeGroupUser(String groupId, String userEmail) {
  BoxGroup boxGroup = new BoxGroup(this.boxAPI, groupId);
  Iterable<BoxGroupMembership.Info> memberships = boxGroup.getAllMemberships();
  for (BoxGroupMembership.Info membershipInfo : memberships) {
    if (membershipInfo.getUser().getLogin().toUpperCase().equals(userEmail.toUpperCase())) {
      BoxGroupMembership membership = new BoxGroupMembership(this.boxAPI, membershipInfo.getID());
      membership.delete();
    }
  }
}

前の手順が完了していません

最初に、手順1でお好みの言語/フレームワークを選択してください。

このコードでは、SlackのチャンネルIDとなるグループIDを取得し、グループの全メンバーを取得します。メールアドレスに基づいて、Slackチャンネルを退出したユーザーに一致するメンバーが見つかると、そのユーザーはそのメンバーシップIDを使用してグループから削除されます。

データストアによるパフォーマンスの向上

グループメンバーシップを検索してメンバーシップIDを取得すると、ローカルのデータストア (データベースなど) にメンバーシップIDを保存する必要はなくなりますが、ユーザーレコードとともにBoxメンバーシップIDを保存するデータストアがあれば、このコードがより効率的なものになります。

ローカルのデータストアを使用すると、メンバーシップIDは、そのデータストアから取得できます。Box APIを繰り返し呼び出してメンバーシップIDを検索する必要はありません。

グループ名に対応したBoxグループIDの取得

次に必要なBox関数には、主に2つの目的があります。

  • 既存グループのBoxグループIDを返します。
  • グループが存在しない場合、Boxグループを作成してそのIDを返します。

getGroupId関数を次の内容に置き換えます。

function getGroupId(groupName, callback) {
    client.groups.getAll().then((groups) => {
        const group = groups.entries.filter((g) => g.name === groupName)[0];

        if (!group) {
            client.groups
              .create(groupName, {
                  description: "Slack channel collaboration group",
                  invitability_level: "all_managed_users",
              })
              .then((group) => {
                  callback(group.id);
              });
        } else {
            callback(group.id);
        }
    });
}

getGroupIdメソッドを次の内容に置き換えます。

public String getGroupId(String groupName) {
    String groupId = new String();

    Iterable<BoxGroup.Info> groups = BoxGroup.getAllGroups(this.boxAPI);
    for (BoxGroup.Info groupInfo : groups) {
        if (groupInfo.getName().toUpperCase().equals(groupName)) {
            groupId = groupInfo.getID();
        }
    }

    if (groupId.isEmpty()) {
        BoxGroup.Info groupInfo = BoxGroup.createGroup(boxAPI, groupName);
        groupId = groupInfo.getID();
    }

    return groupId;
}

前の手順が完了していません

最初に、手順1でお好みの言語/フレームワークを選択してください。

このコードでは、社内のすべてのグループを取得し、SlackチャンネルIDとグループ名の照合を試みます。いずれかのグループが一致すると、そのグループIDが返されます。

一致するものがない場合は、新しいBoxグループが作成され、そのグループのIDが返されます。グループの名前はSlackチャンネルIDに基づいて付けられます。これはスラッシュコマンドとUser Eventの両方で返される定数であり、追加の関数がなくても簡単に検索できるようにするためです。

グループへの共有コンテンツの追加

最終的に、このアプリケーション全体の主な目的は、ユーザーが自分のBoxアカウントにあるファイルやフォルダをグループ内の他のユーザー全員と共有できるようにすることです。

ここまでのすべての機能を基に、次の関数でそのタスクを実行します。

processContent関数を次の内容に置き換えます。

function processContent(user, channel, itemType, itemId) {
    getGroupId(channel, function (groupId) {
        const email = user.profile.email;

        client.enterprise.getUsers({ filter_term: email }).then((users) => {
            if (users.entries.length > 0) {
                client.asUser(users.entries[0].id);
                const collabRole = client.collaborationRoles.VIEWER;
                const collabOptions = { type: itemType };

                client.collaborations
                    .createWithGroupID(groupId, itemId, collabRole, collabOptions)
                    .then((collaboration) => {
                        console.log(
                            `Content added with collaboration ID ${collaboration.id}`
                        );
                    })
                    .catch(function (err) {
                        console.log(
                          util.inspect(err.response.body, {
                              showHidden: false,
                              depth: null,
                          })
                        );
                    });
            }
        });
    });
}

processContentメソッドを次の内容に置き換えます。

public void processContent(JSONObject userResponse, String channel, String fType, String fId) {
    String groupId = getGroupId(channel);

    JSONObject userObj = (JSONObject) userResponse.get("user");
    JSONObject userProfile = (JSONObject) userObj.get("profile");
    String userEmail = (String) userProfile.get("email");

    Iterable<BoxUser.Info> users = BoxUser.getAllEnterpriseUsers(this.boxAPI, userEmail);

    for (BoxUser.Info user : users) {
        if (user.getLogin().toUpperCase().equals(userEmail.toUpperCase())) {
            String uid = user.getID();
            boxAPI.asUser(uid);

            BoxCollaborator collabGroup = new BoxGroup(boxAPI, groupId);

            try {
                if (fType.equals("file")) {
                    BoxFile file = new BoxFile(boxAPI, fId);
                    file.collaborate(collabGroup, BoxCollaboration.Role.VIEWER, false, false);
                } else if (fType.equals("folder")) {
                    BoxFolder folder = new BoxFolder(boxAPI, fId);
                    folder.collaborate(collabGroup, BoxCollaboration.Role.VIEWER);
                }
            } catch (Exception ex) {
                System.err.println("Collaboration failed");
            }

            boxAPI.asSelf();
        }
    }
}

前の手順が完了していません

最初に、手順1でお好みの言語/フレームワークを選択してください。

このコードでは、最初に、コンテンツの共有先となるSlackチャンネル用にBoxグループIDを取得します。

スラッシュコマンドを送信したユーザーのBoxアカウントからファイルやフォルダを共有するため、次に、そのユーザーのBoxユーザープロフィールをメールアドレスに基づいて取得します。

最後に、グループIDを使用して、コンテンツでグループとコラボレーションするための呼び出しを行います。

まとめ

  • Boxクライアントをインスタンス化しました。
  • Boxグループユーザーを追加および削除するための関数を作成しました。
  • コンテンツをグループと共有するための関数を作成しました。