SEの技術blogです。GCPあたりが好きです。CRMというCRMのサービスがあるのですが、会社でこれを利用しています。https://www.zoho.com/jp/crm/CRMは顧客の情報を管理するシステムだと思えばOKです。CRMにはAPIがあって、v1を使っているのですが、v1は2019/12/31にサポート終了するので、v2に移行した話です。v1とv2の違い、注意点v1とv2の違いは色々ありますが、こちらにまとまっています。HH:mm:ssの形式だったけど、v2ではyyyy-MM-dd’T’HH:mm:ssTZフィールド名が表示ラベルではなくAPI名になった詳細後述。カスタムフィールドを使う人は特に注意。認証が単純なtoken方式ではなくOAuthになった。認可もあるので権限要求に注意です。これらに触れつつ、解説していきます。APIを使うための準備(ZohoCRMアカウントは登録するだけです。用意されている前提)APIは認証が必要なので、まずは認証を突破するための準備を行います。基本的にはここに従うだけですが、結構はまりました・・。v1時代に使っていたtoken生成の画面は一切使いません。開いて、クライアントの登録を行います。Secretが生成されるのでこれをメモしておきます。Tokenを生成します。https://www.zoho.com/crm/developer/docs/api/auth-request.htmlこちらによるとHTTP(CLI)による生成も可能ですが、ブラウザによるGUIでの生成も可能です。Self-Clientというところから生成するのですが、このときScopeに設定するものはこちらに書かれています。https://www.zoho.com/crm//developer/docs/api/oauth-overview.html#scopesAPIで操作したいものを入力します。APIでZohoCRMのユーザだけ操作したいのであればZohoCRM.users.allと入力すれば良いです。ContactやAccountなども操作したいのであればZohoCRM.modules.contacts,ZohoCRM.modules.accountsなども追加します。自分の場合はこうしました。(ほぼなんでもOK)ZohoCRM.users.all,ZohoCRM.org.all,ZohoCRM.settings.all,ZohoCRM.modules.all,ZohoCRM.bulk.all権限の範囲を狭めたりきっちり管理したい人はドキュメントを読むと良いかと思います。Expiryは10分などに設定しておいてください。Tokenの有効期限です。Tokenが生成されますので、それをメモして、次の手順を10分以内に行います。GrantTokenを自分が生成したものに変更して、上記のPOSTを行います。https://accounts.zoho.comにアクセスしていますが、契約しているZohoがEUなどの場合https://accounts.zoho.euなど、適宜変更します。このcurlで以下のようなjsonがかえってきます。3600000}access_tokenとrefresh_tokenをメモしておきます。expires_in_secとexpires_inは3600秒(3600000ミリ秒)つまり1時間でaccess_tokenが有効切れになるということを意味しています。refresh_tokenは無期限です。漏洩するなどした場合は専用のAPIで失効させましょう。リクエストの実験とrefresh_token上記の手順でaccess_tokenが生成できました!というわけでこれを使ってアクセスしてみましょう。Zoho-oauthtokenヘッダに入れます。bar","Record_Image":null,"$review":null,"Phone":null,"Account_Name":{"name":"foobar株式会社","id":"3333333"},"Email_Opt_Out":false,"Modified_Time":"2019-10-03T18:42:00+09:00","Title":null,"Mobile":null,"field1":null,"First_Visited_Time":null,"Last_Name":"foo","Referrer":null,"field7":false,"field6":null,"Tag":[],"Fax":null,"field3":null,"field2":null,"field5":false,"field4":null},..access_tokenは1時間で失効します。その場合はrefresh_tokenを使って新しいaccess_tokenを生成します。"https://accounts.zoho.com/oauth/v2/token?refresh_token=上記で生成されたRefreshToken&client_id=上記で(略)&client_secret=上記で(略)&grant_type=refresh_token"これで新しいAccessTokenが返ってくるのでそれを使ってまたアクセスします。このTokenのRefreshは大抵のOAuthに対応したAPIライブラリならばやってくれることでしょう。Railsを使っていて、Rubyのzoho_hubというライブラリがあるので、今回はこれを利用しました。APIの注意点などを説明していきます。https://github.com/rikas/zoho_hub基本的にREADMEに従って設定して使うだけですが、一部苦労したので、そこについて解説します。Tokenの設定(この部分の理解が甘いですが)おそらく、GrantTokenのCLIによる生成はできないと思います。zoho_hubではZohoHub::Auth.urlでGrantTokenを生成するURLを発行していますが、これはブラウザでアクセスする必要があるのかと思います。今回私が作成するプログラムはJob(GUIなし)なので、ブラウザアクセスを挟む余地はありません。params[:refresh_token])refresh_tokenというメソッドにRefreshTokenを与えると新しいAccessTokenを生成してくれます。それを使ってconnectionを初期化するようにしました。RefreshTokeは失効しないので、これで安定してAPIを使い続けることができます。いうように使うことができます。これはhttps://www.zohoapis.com/crm/v2/leadsにGETをしています。postやputもあり、jsonを引数にします。この方法でもいいのですが、ActiveRecordのようにmodel(class)を経由して使うこともできます。READMEにサンプルがありますし、ここのディレクトリにもサンプルがあります。leadlead.saveカスタムフィールドを使っている場合は特に注意。jsonのkey名は項目名ではなくAPI名を使う例えば資料請求日というカスタムフィールドを作成したとします。)endこの場合、リクエストは成功しますが、資料請求日は更新されません。APIではリクエスト時のjsonのkey名は項目名ではなくAPI名を使う必要があります。API名は以下のURLで確認することができます。https://crm.zoho.com/crm/settings/api/modulesこの画像の例だと「あいう」という項目名ですが、API名は「field2」となっていますね。API名を編集して好きな名前をつけると良いかと思います。「Document_Request_Date」とか。:field2)こうですね。attribute_translationを使わずにattributeを:field2とする方法は?と思いますが、それは多分動きません。“foo”というJsonになります。API名を大文字にするかattribute_translationを使うか、どちらかが良いです。APIで一発で全件取得はできない。Stringの?page=1&per_page=200が必要、です。GETすることで複数のデータを一度に取得できます。levelにはdataとinfoというkeyがあり、dataが配列になっているので、ここに複数入っています。デフォルトだと最大の200件なので、一度に全件取得はできません。いうようにページを変える必要があります。allにはparamsという引数があるので、pageを指定してあげればOKです。ちなみに次のページを要求する必要があるのかどうかはdataではなく、infoのmore_recordsを見れば良いです。zoho_hubで全件リクエストが面倒なので再帰的に全部取るメソッドを用意するPR予定。endendendわりと適当です。改良したい人はどうぞ。CustomResponseはinfoを見るようにするために必要です。Zoho::CustomBaseRecordというように継承元を変えて、all_recursivelyを呼べばOKです。したいzoho_hubでBaseRecordを使う方法を書きました。BaseRecordを使う場合はsaveメソッドを呼ぶことでPOSTまたはPUTすることができます。この方法だと1件の更新なので、対象とするレコードが500件とかあると大変です。creditも使います。creditはアカウントの契約状態によりますが、5000-15000/24hくらいあると思っておけばいいです。無茶な使い方をすると制限にひっかかります。insert/updateを行いたいところです。これは考慮されていて、以下で確認することができます。APIはcsvを作成し、アップロードし、そのcsvを取り込むjobを作るリクエストを行う、というちょっと面倒だけど強力なものです。一度に25000件まで行けるようですね。Records)の方を使いました。使い方は簡単で、data配列に複数のデータを詰めてtriggerを付けてPOSTするだけです(更新ならPUT)詳細はリンク先でサンプルを見れます。POSTこれをzoho_hub経由でやります。以下のようにやればOKです。'approval'}.to_json)BaseRecordにto_paramsというメソッドがあるのでこれでまずHashに変換します。keyを付けた完全なHashを作り、最後にjsonにしてPUTでリクエストしています。(PUTの場合、data内の各レコードにidフィールドが必要。更新なので当たり前ですね。POSTの場合は不要です。いうように大文字になってしまいます。小文字でないとエラーが出ます。'Account_Name:starts_with:(株)abc')一見うまくいきそうな検索ですが、これはエラーになります。Integer)これは()をエスケープしていないためです。(Last_Name:starts_with:Patricia\,Boyle)https://www.zoho.com/crm/developer/docs/api/search-records.html()と,はエスケープが必要なようですね。いうわけで以下は成功します。encodeする必要があります。(は%28)は%29\は%5C,は%2Cです。libraryが持ってて良い機能だと思うので、そのうちPRしてみようかと思います。APIを利用するみなさんの助けになれば幸いです。PM参考になりました、ありがとうございます。私もZOHOを使っていまして、V1からV2に現在悪戦苦闘しております、このページを参考にAccessTokenとRefreshTokenの取得はできたのですが、「4」の段階でcurlでリクエストしても何も返ってきません、正確にいうと返信はあるのですが、何も値がありません。間違えたTokenを入れてみたら認証失敗エラーがでてきたのですが、正しいTokenを入れると、値無しで実行されます、これはどういった現象でしょうか?もしアドバイス頂けたら幸いです。PMすいません、解決しました実行結果通り、Contactsの中にデータが入ってなかっただけでした。AM気づくの遅くてすみません。解決された様で何よりです。コメントをキャンセルメールアドレスが公開されることはありません。*サイト次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。...自宅のサーバやクラウド環境のメモ自分用のメモです。スポットインスタンスの話です。Pub/Subについてまとめていきます。今日はebコマンドのエラーの話です。Datadogの解説!こんにちは、@s_tsukaです。Gateway解説!こんにちは、@s_tsukaです。...Python標準csvで改行ありエスケープありCSVを読み込むすごく些細なことなのにつまづいてしまったのでメモ。誰かの役に立てば良いです。仕事で多言語対応(i18n対応)をしたのですが、なかなか苦労しました。SEの技術blogです。GCPあたりが好きです。