NEWS

[kintone]JavaScriptを用いて別アプリからデータを取得しよう

2023.2.14
Jumpei Yamamoto

JavaScriptカスタマイズを行うことによってkintoneの標準機能ではできないことを実現することができます。しかし、初心者の方にとっては少しハードルが高いですよね。複数のアプリが関わってくるとAPIや非同期処理が絡んできて、他の人が作成したコードを見てもその内容を理解できないことが多いと思います。

今回は、kintoneの標準機能では行うことのできない「別アプリのテーブル情報を取得する」機能を実現することを念頭に、一緒にアプリを作成していきましょう。

本記事はこのような方におすすめ!

  • プログラミング初心者
  • kintoneの初歩的なJavaScriptカスタマイズを行ったことがある
  • APIや非同期処理を含んだカスタマイズに挑戦したい

アプリの概要

活動記録とプロジェクト管理という2つのアプリを作成します。今回カスタマイズを実装する活動記録の機能は、「活動内容・プロジェクト名などmtgに関するデータを入力し、その記録を一覧で表示する」ということになります。活動記録のアプリでレコードを作成する際、プロジェクト名を入力した際に、プロジェクト管理のアプリを参照して、共有先メンバーを自動的に追加できるようカスタマイズを行います。

2つのアプリのフィールドの詳細は以下のようになります。

活動記録のアプリを作成する際に、プロジェクト名に応じたメンバー情報をテーブル(共有先)にコピーするように設定できれば良いのですが、冒頭でも述べたようにkintoneの標準機能では別アプリのテーブルをコピーすることができません。

では、ここから以下の流れに沿ってJavaScriptのカスタマイズを作成していきましょう。

  1. 活動記録のテーブル[共有先]に入れる値の種類に応じて、配列変数を用意
  2. kintone REST API を使用して、プロジェクト管理のテーブル[メンバー]の値を取得し、それぞれの配列変数に要素を追加(get_shareData関数の定義)
  3. 各配列に全ての要素が入ったら、活動記録のテーブル[共有先]の値を更新(make_result関数の定義/Promiseで処理順序の制御)

1.活動記録のテーブル[共有先]に入れる値の種類に応じて、配列変数を用意

kintone.events.on([  
		'app.record.create.change.開始日時', 'app.record.edit.change.開始日時'], (event) => {
		const shareMem = [];
		const shareDep = [];
		const shareMail = [];
		const sharePart = [];

まず、kintone.events.on() メソッドを使用して、「プロジェクト開始日時」フィールドの値が変更されたときに実行される関数を定義します※。次に氏名・部署・メールアドレス・役割に分けて4つの配列変数を用意します。

※ イベントタイプについて

プロジェクト名が変更された際に共有先テーブルに情報を格納したいので、「レコードの作成・編集時にプロジェクト名が変更された時[‘app.record.create.change.プロジェクト名’, ‘app.record.edit.change.プロジェクト名’]」を指定したくなります。しかし、ルックアップのフィールドはフィールド値変更時イベントで指定できません。そのため、今回はプロジェクト名をルックアップで取得した際にコピーされる別のフィールド”プロジェクト開始日時”を設置し、”プロジェクト開始日時”の値の変更をトリガーにすることにしました。

2.kintone REST API を使用して、プロジェクト管理のテーブル[メンバー]の値を取得し、それぞれの配列変数に要素を追加(get_shareData関数の定義)

get_shareData関数の中で、プロジェクト管理からデータを取得することにします。そのような機能を果たすためにはkintone REST APIを利用することになります。kintone REST APIの基本形は以下のようになります。

kintone.api(pathOrUrl, method, params, successCallback, failureCallback)

各パラメータに何を入れるかは、利用するkintone REST APIに応じて変化します。差し当たって私たち初心者は、methodのパラメータにGET(取得), POST(登録), PUT(更新), DELETE(削除) を指定できることを覚えておきましょう。何ができるのかを理解しておけば、cybozu developer networkのページから基本的な形を参照することができます。

レコードの取得(GET)/レコードの登録(POST)/レコードの更新(PUT)/レコードの削除(DELETE)

const record = event.record;
const proName = record.プロジェクト名.value;
const body = {
	'app': ”アプリID”,
	'query': 'プロジェクト名 = "' + proName + '"',
	'fields': ['メンバー']
};

function get_shareData() {	
	kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body,
		function(resp) {
			resp.records.forEach(function(record) {
				const memTable = record.メンバー.value;
				for (var t = 0; t < memTable.length; t++) {
					shareMem.push(memTable[t].value.氏名.value);
					shareDep.push(memTable[t].value.部署.value);
					shareMail.push(memTable[t].value.メールアドレス.value);
					sharePart.push(memTable[t].value.役割.value);
				}
			});
		});	
}

今回は特定のアプリのレコードを条件付けて取得(GET)したいので、レコードの一括取得APIを参考に進めます。基本的には掲載されている形のまま利用できますが、自分でbodyを宣言し、取得したい情報を指定する必要があります。今回はプロジェクト管理において、”プロジェクト名”フィールドに入力したプロジェクトのレコードの、フィールドコードが”メンバー”である部分を指定しています。レコード取得が成功した場合には、1.で用意した配列変数に、得られたテーブルの各要素を追加します。

ちなみにテーブルの値を指定するのがややこしいですが、以下の画像をイメージするとわかりやすいと思います。この例では、フィールドコードが”共有先”のテーブルの3行目、中居さんの役割部分を指定していることになります。

3.共有先テーブルの値を更新

・make_result関数の定義

function make_result() {
	const record = kintone.app.record.get().record;
	const shareTable = record.共有先.value;
	while (shareTable.length > 0) {
		shareTable.splice(0, 1);
	}
	for (var i = 0; i <= shareMem.length - 1; i++) {
		shareTable.push({
			value: {
				"共有者": {
					value: shareMem[i],
					type: "SINGLE_LINE_TEXT"
				},
				"部署": {
					value: shareDep[i],
					type: "DROP_DOWN"
				},
				"メールアドレス": {
					value: shareMail[i],
					type: "LINK"
				},
				"役割": {
					value: sharePart[i],
					type: "SINGLE_LINE_TEXT"
				},
				"連絡確認": {
					value: [],
					type: "CHECK_BOX"
				}
			}
		});
	}
	kintone.app.record.set({
		record: record
	});
}

make_result関数では、一旦活動記録のテーブル[共有先]の初期化を行った後、2.で完成した各配列の要素を追加する処理を行なっています。テーブルに要素の追加を行う処理ですが、ここで一つ注意点があります。テーブルに行の追加を行う際は、値だけでなく、必ずフィールドタイプの指定が必要です。文字列(1行)ならSINGLE_LINE_TEXT、数値ならNUMBERのように各々指定する必要があります。この指定を行わないと、エラーが発生するので注意しましょう。

フィールド形式の詳細についてはこちらをご覧ください。

・Promiseで処理順序の制御

REST APIは非同期処理のため、APIの実行が完了する前に後続のコードが走ってしまうことになります。そのため、処理順序を制御することが必要になります。今回は、get_shareData関数の処理が完了してから、make_result関数の処理を実行するようにコードを書く必要があります。

非同期処理を上手に利用することは難しいですが、Promiseの基本的な活用方法を紹介するので、イメージを掴んで頂ければと思います。Promiseオブジェクトは、第一引数にresolve,第二引数にrejectを設定し、resolveした場合にはthenの処理が、rejectした場合にはcatchの処理が走ることになります。第二引数のrejectの設定は任意になります。今回はresolveのみ記述しています。

get_shareData関数内で、各配列変数への要素追加の処理が完了したらresolveとします。2.のコードに以下のようにPromiseの処理を追加します。

function get_shareData() {
	return new Promise(function(resolve) {
		kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body,
			function(resp) {
				resp.records.forEach(function(record) {
					const memTable = record.メンバー.value;
					for (var t = 0; t < memTable.length; t++) {
						shareMem.push(memTable[t].value.氏名.value);
						shareDep.push(memTable[t].value.部署.value);
						shareMail.push(memTable[t].value.メールアドレス.value);
						sharePart.push(memTable[t].value.役割.value);
					}
					resolve();
				});
			});
	});
}

そして、thenの処理にmake_result関数を入れます。これで、各々の配列に取得した要素が追加された後に共有先テーブルのデータを更新できるようになります。

get_shareData().then(function() {
	make_result();
});

実装したコード全文は以下になります。

(() => {
  'use strict';
  kintone.events.on([ 'app.record.create.change.開始日時', 'app.record.edit.change.開始日時'], (event) => {
    const shareMem = [];
    const shareDep = [];
    const shareMail = [];
    const sharePart = [];
    const record = event.record;
    const proName = record.プロジェクト名.value;
    const body = {
      'app': ”アプリID”,
      'query': 'プロジェクト名 = "' + proName + '"',
      'fields': ['メンバー']
    };

    function get_shareData() {
      return new Promise(function (resolve) {
        kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body, function (resp) {
          resp.records.forEach(function (record) {
            const memTable = record.メンバー.value;
            for (var t = 0; t < memTable.length; t++) {
              shareMem.push(memTable[t].value.氏名.value);
              shareDep.push(memTable[t].value.部署.value);
              shareMail.push(memTable[t].value.メールアドレス.value);
              sharePart.push(memTable[t].value.役割.value);
            }
            resolve();
          });
        });
      });
    }

    function make_result() {
      const record = kintone.app.record.get().record;
      const shareTable = record.共有先.value;
      while (shareTable.length > 0) {
        shareTable.splice(0, 1);
      }
      for (var i = 0; i <= shareMem.length - 1; i++) {
        shareTable.push({
          value: {
            "共有者": {
              value: shareMem[i],
              type: "SINGLE_LINE_TEXT"
            },
            "部署": {
              value: shareDep[i],
              type: "DROP_DOWN"
            },
            "メールアドレス": {
              value: shareMail[i],
              type: "LINK"
            },
            "役割": {
              value: sharePart[i],
              type: "SINGLE_LINE_TEXT"
            },
            "連絡確認": {
              value: [],
              type: "CHECK_BOX"
            }
          }
        });
      }
      kintone.app.record.set({
        record: record
      });
    }
    get_shareData().then(function () {
      make_result();
    });
    return event;
  });
})();

まとめ

以上、Java Scriptを用いて別アプリからデータを取得する方法を紹介しました。

非同期処理に関する制御とREST APIに関する知識を深めて、複雑なカスタマイズにも挑戦してみましょう!!

CONTACT
TwitterFacebook

NEWS