こんにちは、SEタケです。
Webhookで更新前と削除前のレコード情報を使いたい、そういうことはありませんか。
kintoneはシンプルで気軽に使えるツールですが、kintone本体だけでできることは限られています。
追加の機能がほしいときは、主に3つの選択肢があります。
- プラグインを使う
- JavaScriptで実装する
- Webhookでシステム連携
基本的には、プラグインを利用するケースが多いかと思いますが・・
目的に適したプラグインが見つからなかったり、利用料が見合わない場合は、
JavaScriptかWebhookを利用することになりますね。
簡単な処理や画面制御はJavaScriptでもできますが、
複雑な処理や、外部サービスへの連携が必要だったりする場合は、Webhookが便利です。
例えば、集計処理や引き当て処理、メール/SNS/カレンダー/Web会議への連携処理、などが考えられます。
これらは、WebhookでAzureやPower Automateなどのサービスを呼ぶことで、比較的簡単に実現できますし、ほとんどのケースでプラグインよりも安価になります。
なのですが、kintoneのWebhook機能には、とても残念だと感じる点が1点あります。
それは、削除時/更新時に、削除前/更新前のレコード情報が取得できない、という点です。
この制限を乗り越えるために、少し工夫が必要になります。
今回は、その方法について、解説します。
Webhookを自由に活用するために、とても参考になる内容ですので、ぜひ最後までお読みください。
案件の利益計算を例に考える
まず、説明のための例として、案件の利益計算を考えます。
工事やイベントなど、案件を受託して、計画を立て、いろいろなところに発注したりして目的を達成して、納品する、そういうビジネスがあるとします。
案件の売上から、発注した費用を集計して差し引き、案件ごとの利益を算出する、という流れで考えます。
(実際は、人件費や経費なども集計したいところですが、今回は単純化のため、発注だけにします。)
データの構成としては、案件情報に対して、複数の発注情報が紐づく構成とします。
kintoneアプリの構成としては、下記のようになります。
- 「案件情報アプリ」と「発注情報アプリ」を作成
- 「発注情報アプリ」に「案件情報アプリ」へのルックアップフィールドを設置
- 「発注情報アプリ」には「発注額」、「案件情報アプリ」には「売上」と「発注額の合計」フィールドを設置
- 「案件情報アプリ」に「利益」(売上ー発注額の合計)の計算フィールドを設置
発注情報を追加/編集すると、案件情報に発注額の合計が自動で集計され、案件ごとの利益が算出される、という仕組みが目標です。
kintone本体だけの機能では、これは実現できません。
このようなケースでよく使われるプラグインの一つに、krewDataがありますが、今回これは使わないこととします。
また、APIや関連レコード一覧を使ってスクリプトで発注額を合計する、という方法も考えられますが、一覧や詳細など画面ごとに処理を作成する必要があるなど、複雑になってしまいます。
ということで今回は、Azureに集計処理を作成し、Webhookを使ってそれを実行する、という方法をとることにします。
Azureで集計処理を実装
Azureでの集計処理は、まずは下記のような処理にします。
- 「発注情報アプリ」のレコード追加/更新時に実行(Webhookで呼び出し)
- 追加/更新された発注情報と同じ案件に紐づく発注情報を、kintoneのAPIで取得し、発注額を合計
- 発注額の合計(2で計算したもの)を、「案件情報アプリ」の「発注額の合計」フィールドにAPIで更新
これで、「発注情報アプリ」のレコード追加/更新時の仕組みは、できました。
下記のパターンでは、発注額の合計が計算されるようになりました。
- 発注情報の追加
- 発注情報の発注額を変更
ですが、これだけでは充分ではありません。
下記のケースの考慮がもれていますね。
- 発注情報を削除したとき、削除された発注情報に紐づく案件の、発注額合計を計算しなおす
- 発注情報の案件を付け替えたとき、変更前の発注情報に紐づく案件の、発注額合計を計算しなおす
ここで、問題が出てきます。
kintoneのWebhookは、レコードが追加/更新/削除された後に実行されるのですが、
「削除/更新前のレコード情報が渡されない」のです。
困りました。
削除/更新前の発注情報に紐づく案件がわからなかったら、どうやって案件の発注額を集計しなおせばいいのか。。
これを実現するためには、少し小細工が必要になります。
小細工は、削除と更新(案件の付け替え)で異なりますので、それぞれ説明します。
小細工の前準備(共通)
結局のところ、発注情報の削除/更新時に、削除/更新前の案件が、Webhookに渡せればいいわけですよね。
ということは、予めそれ用のフィールドを用意して、Webhookで渡すようにすればよくないですか。
ということで、共通の前準備として「発注情報アプリ」に「更新前の案件」フィールドを追加します。
発注情報の更新/削除前に紐づいていた案件を、このフィールドを使ってWebhookに渡す、という考えです。(方法は後述します)
また、Azureでの集計処理に下記の処理を追加します。
- 「更新前の案件」フィールドに値が入っていて、「案件」の値と違う(変更された)ときは、追加の処理(下記2)を行う
- 更新前の案件に紐づく発注情報(「案件」=更新された発注情報の「更新前の案件」)についても、発注額の集計を行う。
「更新前の案件」フィールドは手で変更はしてほしくないので、スクリプトで非表示にしておくと、よりいいですね。
発注情報を削除したときの小細工
削除時のWebhookでは、削除前のレコード情報どころか、レコード情報自体が渡されません。
ですので、削除時はWebhookを呼ばず、更新時のWebhookを利用します。
どういうことかというと、
スクリプトで、発注情報の削除直前に、APIでレコードを更新して、強制的に更新時のWebhookを実行させるようにします。
その際、APIで更新するレコードの値は、下記を指定します。
- 「更新前の案件」=「案件」 (削除前に紐づいていた案件の発注額合計を再計算するため)
- 「案件」=空 (発注額の集計に、削除レコードを含めないため)
スクリプトの処理を実行するイベントとしては、下記になります。
- app.record.detail.delete.submit(詳細画面でのレコード削除)
- app.record.index.delete.submit(一覧画面でのレコード削除)
これによって、下記の流れになります。
- 削除前にスクリプトでレコードを更新
- 更新時のWebhookが呼ばれ、削除レコードを除いた発注額の合計が再計算される
- レコード削除
削除については、これで解決ですね。
発注情報を更新(案件付け替え)したときの小細工
次は、更新時の小細工です。
削除時の小細工と同様でいいのでは?
と思われた方もいるかもしれません。
- 削除前にスクリプトでレコードを更新
- 更新時のWebhookが呼ばれ、更新前レコードを除いた発注額の合計が再計算される
- レコード更新
- 更新時のWebhookが呼ばれ、更新後レコードを含む発注額の合計が計算される
で、オッケー!
・・実は私もそう思いました。
ですが、更新のときは、誰かが先に更新しているときは、エラーになるんです。
先ほどの手順1で更新されているので、3でエラーになって更新できない、ということになります。
ということで、同じ手は使えません。
ではどうするかというと・・
更新画面を開いたときと、一覧で更新アイコンをクリックしたときに、
スクリプトで「更新前の案件」フィールドに「案件」フィールドの値を予めコピーしておきます。
スクリプトの処理を実行するイベントとしては、下記になります。
- app.record.edit.show
- app.record.index.edit.show
これによって、下記の流れになります。
- 更新の入力前に、更新前の案件を退避
- 更新時にWebhookが呼ばれ、更新前レコードを除いた発注額の合計と、更新後レコードを含む発注額の合計が計算される
更新(案件付け替え)についても、これで解決ですね。
まとめ
具体的なスクリプトソースやAzureのロジックなどは、今回は提供しませんでしたが、
大まかな方法としては、ご理解いただけたのではないかと思います。
この方法を応用して、kintoneをどんどん便利にしていきましょう。
スクリプトソースやAzureロジックのサンプルは、また公開したいと思います。
以上、最後までお読みいただき、ありがとうございました。
コメント