定期実行でデータの同期を実現するスマートな方法 その1〜cli-kintone編〜

著者名: クローバ株式会社 (External link) 門屋 亮 (External link)

目次

caution
警告

この記事では ver. 0.x.x の cli-kintone を使って説明しています。 ver.1.0.0 以降の cli-kintone の使い方は、次のページを参照してください。
kintone コマンドラインツール(cli-kintone)

はじめに

こんにちは、クローバの門屋です。
kintone は単体でも十分便利なものですが、社内のデータと連携して使いたいというシーンはかなりあると思います。
たとえば社内システムの社員マスターや顧客マスターと連携する場合や、集計した結果のみを kintone に保存したい場合などが考えられます。
自分で実装する場合には REST API を使った連携が定石ですが、API の仕様を理解する必要があるため、敷居の高さを感じる方も多いでしょう。

ここでは kintone のコマンドラインツールの cli-kintone を定期実行させて、2 つのシステム間のデータ同期をとる方法について説明します。
今回はインポートとエクスポートどちらでも流用しやすいように、2 つの kintone のデータを同期するシナリオを考えてみたいと思います。

2 つの kintone がそれぞれ別のドメインで運用されています。ドメイン A のアプリ A から、ドメイン B のアプリ B へと、毎日深夜に、前日更新分のデータを同期します。

なにはともあれ、cli-kintoneについて

cli-kintone はコマンドライン上から kintone にデータをインポート・エクスポートできるツールです。Windows/Linux/Mac 版が提供されています。cli-kintone についての説明は以前 詳しい記事 を書いたので、こちらを確認してください。

具体的な活用のし方はこちらも参考にしてみてください。

同期するアプリについて

cli-kintone を使えばサブテーブルや添付ファイルのインポート・エクスポートも可能なので、たいていのデータは同期が可能ですが、以下の同期はできません。

  • カテゴリー
  • ステータス
  • 作業者

また以下の注意点があります。

  1. 両方のアプリのフォームに作成日時フィールドと更新日時フィールドを含める必要があります。
  2. 顧客コードなど、キーとなるフィールドを用意する必要があります。キーとなるフィールドはアプリの設定で重複を禁止してください。
  3. コピー元、コピー先両方の API トークンが必要です。コピー元の API トークンには閲覧権限、コピー先の API トークンにはレコード追加、レコード更新、アプリ管理権限を設定してください。

前日追加されたデータを取得する

cli-kintone を使って前日追加されたデータを取得するには、次のようなコマンドを実行します(前日の日付を 2016/11/1 としています)。

1
./cli-kintone -d $DOMAIN_A -a $APP_ID_A -t $API_TOKEN_A -q "作成日時 >= \"2016-11-01\" and 作成日時 < \"2016-11-02\"" > new_records.csv
変数
$DOMAIN ドメイン
$APP_ID アプリID
$API_TOKEN APIトークン

$DOMAIN_A はドメイン A の値を表します。

前日更新されたデータを取得する

同様に、前日更新されたデータを取得するには、次のようなコマンドを実行します。

1
./cli-kintone -d $DOMAIN_A -a $APP_ID_A -t $API_TOKEN_A -q "作成日時 < \"2016-11-01\" and 更新日時 >= \"2016-11-01\" and 更新日時 < \"2016-11-02\"" > updated_records.csv

データを追加、更新する前に

次に、取得したデータファイルを使って、ドメイン B のアプリに追加、更新するわけですが、注意点があります。

CSVファイルに$idフィールドが存在すると、レコード番号でデータが更新される

今回はレコード番号以外のキーフィールドで更新したいわけですから、CSV ファイルから$id フィールドを削除する必要があります。
cli-kintone の仕様により、-c オプションでフィールドを指定しない場合、1 列目はレコード番号となり、2 列目はリビジョン番号となりますので、これらを削除します。

特定キーで更新するには、CSVファイルのヘッダーに「*」をつける

たとえば、フィールドコードが"code", "name", "address"とあって、"code"フィールドをキーにして更新する場合は、次のようになります。

1
2
"*code","name","address"
"123","山田 太郎","東京都豊島区"

上記 2 点の変換をする必要があります。今回は Python を使って変換スクリプトを書くことにしました。

conv_csv.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env python
import csv
import sys

argvs = sys.argv
argc = len(argvs)

reader = csv.reader(sys.stdin)
out = csv.writer(sys.stdout)
header = []
try:
  header = next(reader)
except StopIteration:
  quit
if (argc > 1):
  for i, fld in enumerate(header):
    if (fld == argvs[1]):
      header[i] = '*%s' % fld
out.writerow(header[2:])

for row in reader:
  out.writerow(row[2:])

あらためて、データを追加、更新する

上で作成したフィルターを使って変換したファイルを使って、ドメイン B のアプリを更新します。コマンドは以下のようになります。

1
2
./cli-kintone -d $DOMAIN_B -a $APP_ID_B -t $API_TOKEN_B -f new_records.csv
./cli-kintone -d $DOMAIN_B -a $APP_ID_B -t $API_TOKEN_B -f updated_records.csv

ここまでの処理をシェルスクリプトにまとめました。

copy2kintone

 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
#!/bin/bash
cd `dirname $0`

# 定数の定義
APP_ID_A=998
DOMAIN_A="domaina"
API_TOKEN_A="ELH834tmgivQFyk4ZYmyyVmJPZgrld9VqSnP3HtU"
APP_ID_B=999
DOMAIN_B="domainb"
API_TOKEN_B="8Nt48J7iwf2evOjxKWIMlX3FYK89hBcgnUWzAi70"
KEY_FIELD="key_field"

DATE_TO=$(date +"%Y-%m-%d")
# For GNU
DATE_FROM=$(date -d '1 day ago' +"%Y-%m-%d")
# For macOS
#DATE_FROM=$(date -v-1d +"%Y-%m-%d")

rm -f new_records.csv
rm -f updated_records.csv

./cli-kintone -d $DOMAIN_A -a $APP_ID_A -t $API_TOKEN_A -q "作成日時 >= \"${DATE_FROM}\" and 作成日時 < \"${DATE_TO}\"" | python conv_csv.py > new_records.csv
./cli-kintone -d $DOMAIN_A -a $APP_ID_A -t $API_TOKEN_A -q "作成日時 < \"${DATE_FROM}\" and 更新日時 >= \"${DATE_FROM}\" and 更新日時 < \"${DATE_TO}\"" | python conv_csv.py ${KEY_FIELD} > updated_records.csv
./cli-kintone -d $DOMAIN_B -a $APP_ID_B -t $API_TOKEN_B -f new_records.csv
./cli-kintone -d $DOMAIN_B -a $APP_ID_B -t $API_TOKEN_B -f updated_records.csv

定期実行する

作成したシェルスクリプトを定期実行するため、cron に登録します。
linux の場合、chmod 755 copy2kintone で実行権限を先に付与する必要があります。

1
crontab -e

次のように crontab を編集します。

1
0 3 * * * /home/kintone/bin/copy2kintone

これで、毎日午前 3 時に前日分の同期処理が実行されます。

Windows サーバーの場合はバッチファイルを作成してタスクスケジューラに登録することで同様のことが実現できます。
Windows のシステムと同期するときの注意点としては、同期する側のシステムで Shift-JIS で CSV をインポート・エクスポートすることが多いため、必要に応じて文字コードの変換をしてください。
cron で動かしても実行結果が出ない場合、まず手元でシェルスクリプトを実行し動作確認をしてください。
linux の場合、cron のログを /var/log/syslog で追うことができます。実行結果が出ない場合、ログを確認しましょう。

おわりに

いかがだったでしょうか。
cron と cli-kintone とを組み合わせることで、最小限の手間でデータ同期を実現できることがおわかりいただけたかと思います。
これでこれまで埋もれていた社内のデータも有効活用できますね!

え、深夜に動かすサーバーがない?そんなときは AWS の lambda 上で cli-kintone を動かして定期実行させることもできます。こちらについてもまた機会があれば書いてみたいと思います。

Ver. 0.9.0 以降を利用する場合の注意事項(2018 年 1 月 18 日追記)

この記事で紹介している -f オプションのみ指定してインポートする方法は、2018 年 1 月にリリースされる Version 0.9.0 以降では推奨しない方法です。
Version 0.9.0 以降では、次のように --import オプションを指定する方法を推奨します。

1
cli-kintone.exe --import -f importdata.csv -a 111 -d dev-demo -t xxxxx

現状は、-f オプションのみ指定する方法でも動作します。