Sansan Tech Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

Eight Team kintone連携機能の開発

こんにちは。技術本部 Eight Engineering Unit でエンジニアをしている辻です。

少し前にはなりますが、Eight Teamの新しいオプション機能としてkintoneとの連携機能をリリースしました。 規模的にも結構大きめの開発だったので、具体的にどのように作ったかや、kintone APIの制約についてまとめておこうと思います。

背景・価値

Eight TeamはEightユーザー同士で名刺を共有できるサービスです。 今回開発したのはEight Team上で共有されている名刺をボタン1つでkintoneアプリに同期することができる機能です。

連携先kintoneアプリの情報を設定する

Eight側の各カラムとkintoneアプリ側のフィールドのマッピングを設定する

同期ボタンを押すとkintoneアプリに名刺情報が同期される

従来、Eight Teamの名刺をkintoneにインポートするためには、都度Eight Teamの名刺をCSVでダウンロードしてkintoneアプリのCSVインポートで取り込む必要がありました。その手間を省き、ボタン1つで最新の名刺情報をkintoneへ反映することができることがこの機能の価値です。

Eight Teamでは過去にHubSpot連携機能(顧客のHubSpotに名刺情報を同期できる機能)をリリースしており、その際の顧客フィードバックとして名刺情報の更新に対応してほしいという要望が多く上がっていました。今回はその要望も取り入れ、名刺情報の更新にも対応した仕様になっています。

機能概要

今回のkintone連携機能の設計は主に以下の点を考える必要がありました。

  • 連携方法(認証方法)
    • 何らかの認証方法で認証して、kintone API経由で顧客のkintoneアプリにレコード作成・更新のリクエストができるようにする
  • マッピングの設定
    • Eight側の各カラムをkintone側のどのフィールドに同期するかを設定できるようにする
  • 同期仕様
    • 更新の仕様どのような形にするか

上記とkintone APIの制約について、特に考慮した点をまとめておこうと思います。

認証方法

開発当初、認証方法の候補としてはAPIトークン認証とOAuth認証を考えていました。 しかしkintone APIの仕様調査を進める中で、OAuth認証では顧客自身でOAuth クライアントを追加してもらう必要があると分かりました。ユーザー体験として厳しくなりそうだったため、結果的にAPIトークン認証を採用することになりました。

APIトークン認証にはサブドメインとアプリIDとAPIトークンが必要です。顧客にkintoneアプリ管理画面でAPIトークンを発行してEightに入力してもらいます。APIトークンは暗号化してDBに保存しておくことで、Eight側から顧客のkintoneアプリにレコード作成・更新のAPIリクエストができるようにしておきます。

マッピングの設定

前提として、kintoneアプリのフィールドはフィールド名・フィールドの種類を顧客が自由に決めて作成することができます。

その上で機能仕様としては、Eight側の各カラムをkintone側のどのフィールドに同期するかというマッピングを設定できる仕様としています。

Eight側の名刺の各カラムに対応する同期先フィールドのcodeをEight側DBで保持して、それをもとに同期が行われる作りにしました。

また、2回目以降の同期時にもマッピングを変更できる仕様としました。

今回の同期仕様として、kintoneアプリ側でレコードが手動で更新された場合(EightからのAPIリクエスト以外での更新を指します)、その後は更新されたカラムを同期対象外にするようにしています。 そのため、同期の際には、その時のマッピング情報(どのカラムをどのフィールドに同期したか)を保存しておき、前回同期時と比べてマッピングが変更された場合は、変更されたフィールドに関連するすべてのレコードが更新されるようにしています。

同期仕様

同期仕様をどのような形にするかは非常に悩ましかったのですが、大まかな仕様は以下のようになりました。

  • 同期対象の名刺に関して、kintoneアプリ上にメアドベースでレコードが存在しない場合は新規レコード作成をし、また既に存在していた場合はそのレコードをEight側の最新の名刺情報に更新する。
  • kintoneアプリ側でレコードが手動で更新された場合、その後はそのカラムを同期対象外とする

更新する際に、前回同期時から更新がない場合は更新リクエストの対象から省く・kintoneアプリ側でレコードが手動で更新された場合はその後はそのカラムを同期対象から省くために、前回同期した値はEight側DBに保持する形にしています。

kintone APIの制約

kintone APIにはいくつか制約があり、今回の同期処理を設計・実装する上で特に以下を意識する必要がありました。

リクエストに失敗した場合の対応

kintoneアプリ側でフィールドにバリデーション(必須項目フィールド・文字数制限など)がかかっていた場合は当然エラーが返ります。 複数レコード登録・更新リクエストに失敗した場合、どのレコードが失敗したかは1件ずつしか返りません。失敗したレコード以外のレコードも全て登録・更新が失敗するので、失敗した際には該当のレコードを省いて再度リクエストする形で実装しました。

id以外をキーとしたレコード更新リクエストに関して、キーとなるフィールドの制約

id以外をキーとして更新リクエストを行う場合、キーとなるフィールドにはkintoneアプリ側で必須項目制御・重複禁止制御をかけてもらう必要があります。顧客が既に利用しているアプリに対して同期する想定の場合、そのような制約をかけてもユーザーのユースケース上問題なさそうか等を考慮した上で、idを更新キーにするか・別のフィールドを更新キーにするかを決める必要がありました。

更新リクエストの無駄な通知を無くす

kintoneには通知機能があり、APIリクエストで行ったレコード登録・更新等の操作をkintoneの通知欄で確認することができます。ただし、更新リクエストの通知に関しては、元のレコードから差分がない更新リクエストであっても通知されるようでした。そのため、無駄な通知が飛ばないようにするためには、差分があるレコードだけを更新リクエストの対象にしてあげる必要がありました。

APIリクエスト回数制限

1アプリあたり1日1万リクエストが上限となっています。レコード登録と更新は100件/リクエスト・レコード取得は500件/リクエストが上限で、レコード登録・更新に失敗したリクエストはリクエスト回数に数えられないようでした。 今回のEight Team顧客のユースケースでは問題にならない回数でした。超えた場合でも直ちにAPIレスポンスが返らなくなるわけではないですが、警告メールが届くので注意が必要です。

エラーレスポンス・エラーコード

エラーレスポンス・エラーコードのパターンは実際にAPIを叩いてみないとわかりません。参考になりそうなブログを出してくれている人はいるので参考にしつつ、実際に叩いて確認・ハンドリングするようにしました。

どう活用してもらうか

また、「作ったはいいが、使われない」という状態は避けたかったので、仕様を踏まえてどのように活用できそうかをまとめて営業・CSメンバーに提案と擦り合わせをしました。

  • 基本的にはマスターのアプリとして顧客管理アプリを作ってもらってそこに同期してもらう。
  • 顧客管理アプリ・名刺管理アプリ以外のアプリ(案件管理アプリなど)に対して同期を行うのには適していない。
  • 例えば案件管理アプリに顧客情報・名刺情報を紐付けたい場合は、顧客管理アプリに対して同期した上で別で案件管理アプリを作成し、kintoneのアプリ間連携機能(ルックアップ, 関連レコード一覧, アプリアクション)を用いることを推奨する。上記のアプリ間連携機能に関してもそれぞれどのように使えそうか説明。

上記のように機能でできることの認識を擦り合わせることで、より使われる形でのリリースに近づけたと思います。

特に今回の開発は、リファインメント時点ではやりたいことは定まっているが詳細な同期仕様等は決まっていませんでした。(そもそもkintoneの仕様上どのようにできるのかの知見が当初無かったため。) 開発側でkintone側の仕様を元にできることを整理して、ベストと考えられる仕様を一から定義して進めていたため、このアクションは一定意義があったと感じています。

まとめ

結果的に大きな問題なく機能をリリースすることができ、Eight Teamの価値向上に貢献することができました。

kintoneアプリとしての制約やkintone APIの制約を考慮した上で、自由度高く同期できる仕様(同期先フィールドのマッピングを自由に設定できて、名刺情報の更新にも対応する)を実現するのは中々複雑で考えることが多かったのですが、だからこそ一定価値につながったと思いました。

シンプルに作るに越したことはないですが、今後も顧客のニーズやユースケースに合わせて適切なものを作っていきたいです。

© Sansan, Inc.