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、LINK | string | リッチエディターはHTML。平坦化せず、HTMLの文字列として読む |
| NUMBER | decimal | スケールはフィールドの表示どおり。kintoneは数値を文字列で保存するので、精度は失われない |
| CALC | decimal または string | フィールドの表示形式による。読み取りのみ |
| DATE | date | |
| TIME | time | 分の精度 |
| DATETIME、CREATED_TIME、UPDATED_TIME | timestamp | kintoneが返すオフセット付きのUTC |
| CHECK_BOX、MULTI_SELECT | array<string> | |
| RADIO_BUTTON、DROP_DOWN、STATUS | string | |
| USER_SELECT、ORGANIZATION_SELECT、GROUP_SELECT、CREATOR、MODIFIER | array<string> / string | コード。名前はユーザーAPIから取る |
| FILE | array<content_ref> | 各ファイルは kintone.contents を通して読める |
| SUBTABLE | array<object> | 各オブジェクトはサブテーブルのフィールドと、そのレコードの id を持つ |
RECORD_NUMBER($id)、$revision | string、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 BY | kintoneが並べ替えられるフィールドで。テキストの並べ替えはコードポイント順で、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