第 9 回 kintone コマンドラインツール(cli-kintone v0)でレコードのデータをもとにマスタアプリのレコードを更新してみよう

著者名: 瀧ヶ平 充 (External link)

目次

information

このチュートリアルは ver. 0.x.x の cli-kintone の使い方を紹介しています。
ver.1.0.0 以降の cli-kintone の使い方を紹介するチュートリアルは次のページを参照してください。
はじめよう cli-kintone

はじめに

今回は、別のアプリから参照している顧客リストの最終訪問日を kintone コマンドラインツール(cli-kintone v0) を使って更新する処理を作成します。

注意事項

第 7 回 第 8 回 に引き続き、高度なコマンドライン操作が必要となるため、今回も bash を前提としています。
Windows をご利用の方は Windows Subsystem for Linux(WSL)上の bash を利用してください。
WSL 上では Linux 用の cli-kintone を使用します。

また、今回は gawk というコマンドを利用します。
使用している環境で利用できない場合はインストールを行ってください。

アプリの準備

今回は 顧客リストアプリ (External link) 商談報告書アプリ (External link) をカスタマイズして使います。
これらのアプリを「 kintone アプリストア (External link) 」から追加しておきましょう。

顧客リストアプリの設定

まず、会社名のフィールドを重複不可の設定にします。
ここではフィールドコードを「Company」とします。

次に、「latest_visit」というフィールドコードで「最終訪問日時」という日時フィールドを作ります。

実運用の際は必要に応じてフィールドを増減させてもよいでしょう。

顧客リストアプリの設定はこれで完了です。

商談報告書アプリの設定

まず、「相手側社名」というルックアップフィールドを作り、以下のようにルックアップを設定します。
フィールドコードは「ルックアップ」とします。

次に、「訪問日時」という日時フィールドを新たに作成するか、すでにある日付フィールドを置き換えます。
こちらはフィールドコードを「visit_datetime」とします。

「商談報告書」のフォーム画面は、このようになります。

API トークンの有効化

cli-kintone でアプリを操作するため、次の API トークンを有効にしておきましょう。

  • 顧客リストアプリ
    • レコード閲覧
    • レコード編集
  • 商談報告書アプリ
    • レコード閲覧

最終訪問日を記録する

顧客リストの最終訪問日を追加、更新します。
以下のコマンドを実行して、商談報告書アプリのレコードに基づいて、最終訪問日を顧客リストのレコードに追加します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
cli-kintone \
  --export \
  -d <kintoneのドメイン> \
  -c "ルックアップ,visit_datetime" \
  -a <商談報告書アプリのID> \
  -t <商談報告書アプリのAPIトークン> \
  -q 'order by visit_datetime asc' | 
  sed "1d" | 
  gawk \
    -v FPAT='([^,]+)|(\"[^\"]+\")' \
    '{date[$1]=$2} END {print "\"*Company\",\"latest_visit\""; for(key in date){print key "," date[key]}}' | 
  cli-kintone \
    --import \
    -d <kintoneのドメイン> \
    -a <顧客リストアプリのID> \
    -t <顧客リストアプリのAPIトークン> \
    -f /dev/stdin

bash では、行の末尾に \ を追加するとコマンドを実行せずに改行できます。
今回はコマンドが長くなってしまったので、これを用いて改行で整形しています。
それでは、パイプで区切った各コマンドについて解説します。

報告書レコードの取得

1
2
3
4
5
6
7
cli-kintone \
  --export \
  -d <kintoneのドメイン> \
  -c "ルックアップ,visit_datetime" \
  -a <商談報告書アプリのID> \
  -t <商談報告書アプリのAPIトークン> \
  -q 'order by visit_datetime asc' |

この部分では、商談報告書アプリからルックアップで取得している会社名および訪問日時を取得し、パイプラインで次のコマンドの入力に渡しています。
次のコマンド以降で処理しやすいように、クエリで条件を指定して表示を訪問日時の昇順で取得しています。
これは簡単ですね。

データの整形

 8
 9
10
11
sed "1d" |
gawk \
  -v FPAT='([^,]+)|(\"[^\"]+\")' \
  '{date[$1]=$2} END {print "\"*Company\",\"latest_visit\""; for(key in date){print key "," date[key]}}' |

この部分は、sed コマンドを用いて 1 行目のヘッダー部分を削除し、その出力を gawk コマンドへ渡しています。
gawk コマンドは、与えられた入力に対して順に 1 行ずつ指定したプログラムを実行します。
今回は指定したオプション、および今回書いたプログラムについてのみ解説します。
gawk の詳細は次のコマンドで確認してください。

1
man gawk
変数への代入
1
gawk -v FPAT='([^,]+)|(\"[^\"]+\")'

gawk コマンドは各行の入力を空白で区切り、区切られた文字列を左から順に $1$2 のようにプログラム内の変数に格納します。
-v というオプションは、プログラムを実行する前に、各行で変数に値を代入できるオプションです。

今回は、変数 FPAT'([^,]+)|(\"[^\"]+\")' という正規表現の値を代入しました。
これによって、カンマで区切るだけでなく " で囲まれた値についても区切って変数で扱えます。

顧客リストの更新用 CSV への整形

では、gawk で処理される以下のプログラムの詳細を確認していきましょう。

1
'{date[$1]=$2} END {print "\"*Company\",\"latest_visit\""; for(key in date){print key "," date[key]}}'
gawk の基本

gawk では {} で囲まれた処理が各行ごとに繰り返し実行されます。

1
2
3
{
  # 処理
}

そこに END を追加すると、繰り返し処理が終わった後の処理を実行できます。

1
2
3
END {
  # 処理
}

gawk では、# で始まる行はコメント行になります。
また、予約語以外なら変数を宣言なしで利用できます。

配列の利用

gawk では配列も利用できます。
たとえば、array という変数に対して array["hoge"]="fuga" を実行すれば、後に array["hoge"] として fuga という値が得られます。
今回のコマンドでは、次のような配列を各行で利用しています。

1
{ date[$1]=$2 }

これは date という配列を用意し、区切られた 1 番目の値を配列のキーとして、2 番目の値をそのキーに対応する値として代入しています。
つまりこの処理では、ルックアップで指定した会社名に対応する値として訪問日時の値を各行上から順に入れていることになります。

さきほどの cli-kintone のクエリ指定で、訪問日時の昇順でレコードを取得しているので、すべての行を読み込んだあとは最新の訪問日時が各会社の最終訪問日の値になります。

繰り返し処理が終了した後の処理

各行の処理が終わった後は END の部分を実行します。

1
2
3
4
5
6
END {
  print "\"*Company\",\"latest_visit\"";
  for(key in date) {
    print key "," date[key]
  }
}

まず、顧客リストの更新用に CSV のヘッダーを print 命令で最初の行に出力します。
会社名のフィールドを指定して更新したいので、*Company* は忘れないようにしましょう。

次に、さきほど使った配列変数 date から for 文を使って CSV の行を出力していきます。
ここでは、配列の添字を変数 key としてループ処理をします。
key は会社名で、date[key] が最新の訪問日時になります。

gawk では、空白で区切ることにより文字列が結合されます。
print key "," date[key] を実行すると、下記フォーマットの CSV 行が作成できます。

1
"会社名","訪問日時"

ここまでの処理で、商談報告書アプリのレコードから会社名と最新の訪問日時のデータを取得し、顧客リストを更新するための CSV ができました。

顧客リストの更新

次に、生成した顧客リストを更新するための CSV を使って顧客リストを更新します。
今回はリダイレクトを使わずに、パイプで cli-kintone に CSV を渡して更新するテクニックを使ってみます。

12
13
14
15
16
17
cli-kintone \
  --import \
  -d <kintoneのドメイン> \
  -a <顧客リストアプリのID> \
  -t <顧客リストアプリのAPIトークン> \
  -f /dev/stdin

現在のところ、cli-kintone ではパイプで渡された値を読み込むことはできません。
しかし、今回のように /dev/stdin/ というパスをプログラムが読み込むことで、パイプラインから渡された値を利用できます。

/dev/stdin というのは標準入力(パイプラインなどで渡されたデータ)にアクセスするための特別なファイルです。
プログラムやシェルスクリプトなどでここにアクセスすると、引数で渡されたものとは別の値を読み込むことができます。

information

Version 0.9.0 から、パイプで渡された値を読み込めるようになりました。

定期的に実行する

定期実行するために、ひとまずさきほどのコマンドをシェルスクリプトにしましょう。
今回も 第 8 回 と同様に実行日時の記録と、エラーログを記録します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/bash

# Sync master app
# Copyright (c) 2020 Cybozu
#
# Licensed under the MIT License
# https://opensource.org/license/mit/

export PATH="$PATH:<cli-kintoneのあるディレクトリ>"
errorLog=<エラーログファイルのパス>

date >> $errorLog

cli-kintone \
  --export \
  -d <kintoneのドメイン> \
  -c "ルックアップ,visit_datetime" \
  -a <商談報告書アプリのID> \
  -t <商談報告書アプリのAPIトークン> \
  -q 'order by visit_datetime asc' 2>> $errorlog | 
  sed "1d" |
  gawk \
    -v FPAT='([^,]+)|(\"[^\"]+\")' \
    '{date[$1]=$2} END {print "\"*Company\",\"latest_visit\""; for(key in date){print key "," date[key]}}' 2>> $errorlog | 
  cli-kintone \
    --import \
    -d <kintoneのドメイン> \
    -a <顧客リストアプリのID> \
    -t <顧客リストアプリのAPIトークン> \
    -f /dev/stdin 2>> $errorlog

今回はこのシェルスクリプトを「update_latest_visit.sh」として保存し、次のコマンドを実行してシェルスクリプトに実行権を設定します。

1
chmod +x update_latest_visit.sh

定期実行の設定は 第 8 回 を参考にして行ってください。

時刻と「update_latest_visit.sh」へのパスを設定したら設定時刻まで待つか、あるいはすぐ近くの日時に設定して動作を確認してみましょう。

information

この Tips は、cli-kintone Ver 0.10.2 と 2020 年 3 月版 kintone で動作を確認しています。