目次
Connector

kintone

kintone Connectorは、kintoneのアプリからレコード、サブテーブル、添付ファイルを読み、レコード、添付ファイル、プロセス管理のステータスを書き戻します。プログラムはこれを使って、問い合わせを分類し、アプリをCRMやDWHと揃え、アプリのワークフローに沿ってレコードを進めます。

読み取り元

  • kintone.<app> — 接続に含めた各アプリが読み取り元です。接続で付けた別名で参照します(kintone.inquiries)。列はアプリのフィールドで、フィールドコードが列名になります。加えて、レコード番号($id)、$revision、作成者、更新者、それぞれの日時があります。キーは $id です。アプリで「値の重複を禁止する」としたフィールドも、UPSERT のキーとして使えます。サブテーブルはオブジェクトの配列として読み、サブテーブルの1レコードが1オブジェクトになります。
  • kintone.attachments — 添付ファイルフィールドのファイル。resource、version(ファイルキー)、record_id、app、field、name、media_type、size。
  • kintone.contents — 添付ファイルのバイト列を content_ref として読みます。resource、version、media_type、content。kintone.attachments から resource と version でJOINしてください。ConnectorはJOINで指定されたファイルだけをダウンロードします。

型

kintoneのフィールドActQL備考
SINGLE_LINE_TEXT、MULTI_LINE_TEXT、RICH_TEXT、LINKstringリッチエディターはHTML。平坦化せず、HTMLの文字列として読む
NUMBERdecimalスケールはフィールドの表示どおり。kintoneは数値を文字列で保存するので、精度は失われない
CALCdecimal または stringフィールドの表示形式による。読み取りのみ
DATEdate
TIMEtime分の精度
DATETIME、CREATED_TIME、UPDATED_TIMEtimestampkintoneが返すオフセット付きのUTC
CHECK_BOX、MULTI_SELECTarray<string>
RADIO_BUTTON、DROP_DOWN、STATUSstring
USER_SELECT、ORGANIZATION_SELECT、GROUP_SELECT、CREATOR、MODIFIERarray<string> / stringコード。名前はユーザーAPIから取る
FILEarray<content_ref>各ファイルは kintone.contents を通して読める
SUBTABLEarray<object>各オブジェクトはサブテーブルのフィールドと、そのレコードの id を持つ
RECORD_NUMBER($id)、$revisionstring、int64アプリコードが設定されていれば $id にそれが含まれる
LOOKUP、REFERENCE_TABLE参照先の型 / 列にならない関連レコード一覧は、プログラム側でJOINとして書く

Effectと操作

レコードのEffectは、アプリのレコードをキーで書きます。

  • insert — EFFECT INSERT kintone.inquiries (subject, body, assignee) VALUES (…)。
  • update — EFFECT UPDATE kintone.inquiries ID `$id` SET (category = …)。
  • upsert — EFFECT UPSERT kintone.customers ID customer_code SET (…)。アプリが重複を禁止しているフィールドをキーにし、kintoneのキー指定更新APIで適用します。
  • delete — EFFECT DELETE kintone.inquiries ID `$id` 。

ID で指定するキーは、ちょうど1件のレコードを識別しなければなりません。$id は常にそうで、一意フィールドはkintoneが制約を強制するのでそうなります。サブテーブルのレコードは親レコードの一部として書きます。SUBTABLEフィールドを設定する更新は、サブテーブルを渡した配列で置き換えます。

コンテンツ:

  • store — EFFECT STORE kintone.attachments SET (record = `$id`, field = 'attachments', content = content) は、レコードの content(SERIALIZE または contents の読み取り元から来た content_ref)をアップロードし、レコードのフィールドに添付します。

操作:

  • update_status — EFFECT COMMAND kintone.update_status TARGET `$id` ID `$id` INPUT (action = 'Resolve', assignee = owner) は、レコードに対してプロセス管理のアクションを実行し、そのアクションの次のステータスに進めます。

セットアップ

"kintone": {
  "connector": "kintone",
  "domain": "acme.cybozu.com",
  "apps": {
    "customers": {"id": 12, "unique": "customer_code"},
    "inquiries": 27
  },
  "credentials": {"api_token": {"env": "KINTONE_API_TOKEN"}}
}

アプリごとに、プログラムに必要な権限を持つAPIトークンを生成します。読み取りにはレコード閲覧、書き込みにはレコードの追加・編集・削除、プロセス管理のアクションにはアプリ管理です。複数のアプリを使うプログラムでは、credentials.api_tokens にアプリの別名をキーにしてトークンを1つずつ書きます。Connectorは、リクエストが触れるすべてのアプリのトークンを送ります。apps のマップで、各アプリidにプログラムで使う名前を付け、必要なら UPSERT 用の一意フィールドを指定します。ユーザーアカウントのパスワード認証も、credentials.username と credentials.password で同じように使えます。ActQL Cloudでは、同じトークンをCloudのシークレットストアに保存します。

Capabilityとプッシュダウン

演算プッシュダウンされる条件
列の選択常に。fields パラメーターで、参照されるフィールドだけをkintoneに求める
WHERE述語が1つのアプリのフィールドに対するもので、kintoneのクエリ言語が正確に対応する演算子を使うとき。=、!=、<、>、<=、>=、IN、NOT IN、LIKE(kintoneの like は単語検索なので、テキストフィールドに対する LIKE '%word%' だけをプッシュダウンする)、IS NULL / IS NOT NULL。TODAY() などの日付関数は、クエリを送る前にHostが評価する
ORDER BYkintoneが並べ替えられるフィールドで。テキストの並べ替えはコードポイント順で、ActQLのバイナリの照合順序と一致する
LIMIT、OFFSET常に。kintoneのオフセット上限10,000件の範囲で。それを超える分は、Connectorが $id の範囲でページングする
GROUP BY、JOINされない。Hostで実行する

プレビューと突き合わせ

プレビュー。 更新、UPSERT、削除、update_status は full_diff です。Connectorは対象の各レコードを読み、値と $revision を記録し、プレビューにはフィールドごとに現在の値と新しい値が出ます(update_status では、現在のステータスと次のステータス)。書き込みはそのリビジョンを付けて送ります。kintoneはリビジョンが合わないリクエストを拒否するので、プレビューのあとで編集されたレコードは、変更を適用するのではなく項目が failed(conflict)になります。追加と添付ファイルのアップロードは targeted です。プレビューには、作成されるレコードやファイルと、その場所がすべて並びます。

突き合わせ。 追加とアップロードにはリクエストのマーカーが付きます。接続のエントリでマーカー用のフィールドを宣言したアプリ("marker": "actql_request")では、マーカーをそのフィールドに書き込み、応答が失われたときはアプリをそのマーカーで検索して突き合わせます。マーカー用のフィールドを宣言していない場合、項目は unknown のままで、何も再送しません。更新とUPSERTは同じリクエストの中で宣言したマーカー用フィールドにもマーカーを書き、レコードを読んでそのマーカーがあることで突き合わせます。$revision が増えていることや承認された値だけでは証跡になりません。削除にはkintoneが保持するマーカーがないので、応答が失われた削除は unknown のままです。何も再送しません。update_status は、kintoneが新しいリビジョンを返した時点で accepted、レコードを読み返して次のステータスが見えた時点で applied になります。

上限と費用

  • kintoneは1リクエストで最大500件を読み、ドメインごとの1日のリクエスト数をプランに応じて制限しています。大きなアプリは、プログラムの件数の上限の範囲でページに分けて読まれ、超えそうな読み取りはエラーで止まります。
  • 書き込みは1リクエストに100件ずつ送ります。各リクエストがEffectの台帳の1項目で、その中のレコードはそれぞれ自分の結果を持ちます。
  • 添付ファイルはkintoneのファイルサイズ上限の範囲で、ダウンロードにはプログラムのバイト数の上限が適用されます。
  • ゲストスペースは別のドメインです。ゲストスペースごとに接続を設定してください。

例

3日以上待たされている問い合わせです。

FROM kintone.inquiries
|> WHERE status = 'Open' AND created_time < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 3 DAY)
|> SELECT `$id` AS record, subject, assignee
|> ORDER BY created_time;

問い合わせを分類して、カテゴリーを設定します。

FROM kintone.inquiries
|> WHERE category IS NULL
|> INFER `model-task:inquiry-category.v1` INPUT (subject, body) AS c
|> WHERE c.outcome = 'ok'
|> EFFECT UPDATE kintone.inquiries
     ID `$id` SET (category = c.value.category);

LLMが回答済みと判定した問い合わせを、アプリのワークフローに沿って解決済みにします。

FROM kintone.inquiries AS i
|> WHERE i.status = 'Answered'
|> JOIN kintone.attachments AS a ON a.record_id = i.`$id`
|> JOIN kintone.contents AS c ON a.resource = c.resource AND a.version = c.version
|> INFER `model-task:inquiry-closed.v1` INPUT (body = i.body, attachment = c.content) AS r
|> WHERE r.outcome = 'ok' AND r.value.closed
|> EFFECT COMMAND kintone.update_status TARGET i.`$id` ID i.`$id`
     INPUT (action = 'Resolve');

Source: actql/actql/docs/connectors/kintone.md at d904416674e4 · Edit on GitHub