Zoho CRM WebAPI v2.1 の SDK を使ってみる話 (php)

Zoho CRM WebAPIのSDKを使おうとしたけど、トークンの発行部分がややこしかった＆あまり情報無かったのでメモとして残しておきます。

## 公式ドキュメント
言葉の意味やスコープの範囲、詳しい使い方などはここを見る。

- API
 - https://www.zoho.com/crm/developer/docs/api/v2.1/
- SDK(PHP)
 - https://www.zoho.com/crm/developer/docs/php-sdk/v4/sample-codes.html

## トークンの種類
先にトークンの種類を認識しておいたほうが良い。個数等の制限は下記の公式で。
[https://www.zoho.com/crm/developer/docs/api/v2.1/token-validity.html](https://www.zoho.com/crm/developer/docs/api/v2.1/token-validity.html)

### Grant Token
- 付与トークン
- 一番最初に一度だけ使う。最大有効時間10分
- このトークンを使ってRefresh Tokenを作る
- API ConsoleのSelfClientから作る

### Refresh Token
- リフレッシュトークン
- 有効期限なし
- Grant Tokenを使って作る

### Access Token
- アクセストークン
- APIのアクセスに使う。有効時間１時間
- Refresh Tokenを使って作る

## SDKを入れる
Zoho CRM API v2.1 PHP用SDK

```bash
$ composer require zohocrm/php-sdk-2.1
```

ログ、設定ファイル用ディレクトリを作っておく。

```bash
$ mkdir logs
$ mkdir conf
```

## トークンの発行
APIにアクセスするにはトークンをDBかテキストファイルに保存する必要がある。今回はテキストファイルに保存する例。

1. API Console([https://api-console.zoho.com/](https://api-console.zoho.com/))でADD CLIENT → Self Client を選択し、Generate Code → Scopeを `ZohoCRM.modules.ALL`（使いたいAPIの内容によって異なる。スコープはAPIのドキュメントに書かれている）で grantToken を発行する。
2. [イニシャライズのサンプルコード](https://www.zoho.com/crm/developer/docs/php-sdk/v4/initialize.html) を良い感じに埋める（下記参照）。初回のみ`->refreshToken`をコメントアウトし、１で取得した`->grantToken`を入力。 ***この時何か適当なAPIを叩くコードを入れておく（後ほど消す）。***（※2021/12時点ではinitializeだけしてもファイルにtokenが書き込まれずハマった。initializeして適当なAPIを叩くとファイルに書き込まれた。） 
2. 実行。今回はコマンドラインで`php initialize.php`した。ログにInitialization successfulと出てれば成功。
3. token.txtにrefreshTokenが書き込まれるので、上記の`->grantToken`はコメントアウトして、`->refreshToken`を記載。
3. ２で入れた適当なAPIにアクセスするコードは消しておく。

※今回はサーバからレコードを取得したいだけだったのでSelf ClientのclientidやclientSecretを使用していますが、サーバサイドベース、クライントベースで使いたい場合は２のclientidやclientSecretをいい感じに変えないと駄目かも知れません（不明）。

![2021-12-08_19h05_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20132/2734ba83-a0a7-b393-e8be-78099dd888a2.png)



initialize.php

```php
<?php
namespace com\zoho\crm\sample\initializer;

use com\zoho\api\authenticator\OAuthBuilder;
use com\zoho\api\authenticator\store\DBBuilder;
use com\zoho\api\authenticator\store\FileStore;
use com\zoho\crm\api\InitializeBuilder;
use com\zoho\crm\api\UserSignature;
use com\zoho\crm\api\dc\USDataCenter;
use com\zoho\api\logger\LogBuilder;
use com\zoho\api\logger\Levels;
use com\zoho\crm\api\SDKConfigBuilder;

// 連絡先取得サンプル用（後から消す）
use com\zoho\crm\api\record\RecordOperations;
use com\zoho\crm\api\ParameterMap;
use com\zoho\crm\api\HeaderMap;

require_once "vendor/autoload.php";

class Initialize
{
    public static function initialize()
    {
        /*
      * Create an instance of Logger Class that requires the following
      * level -> Level of the log messages to be logged. Can be configured by typing Levels "::" and choose any level from the list displayed.
      * filePath -> Absolute file path, where messages need to be logged.
    */
        $logger = (new LogBuilder())
            ->level(Levels::INFO)
            ->filePath(__DIR__ . "/logs/php_sdk_log.log")
            ->build();

        //Create an UserSignature instance that takes user Email as parameter
        $user = new UserSignature("zohoに登録したメールアドレス");

        /*
      * Configure the environment
      * which is of the pattern Domain::Environment
      * Available Domains: USDataCenter, EUDataCenter, INDataCenter, CNDataCenter, AUDataCenter
      * Available Environments: PRODUCTION(), DEVELOPER(), SANDBOX()
    */
        $environment = USDataCenter::PRODUCTION();

        /*
    * Create a Token instance
    * clientId -> OAuth client id.
    * clientSecret -> OAuth client secret.
    * grantToken -> GRANT token.
    * redirectURL -> OAuth redirect URL.
    */
        //Create a Token instance
        $token = (new OAuthBuilder())
            ->clientId("API Consoleで入手したclientId")
            ->clientSecret("API Consoleで入手したclientSecret")
            //->refreshToken("ここはgrantTokenでrefreshTokenを入手(token.txtに入っている)してから入力")
            ->grantToken("API Console → Self Clientで入手したgrant Token（有効時間10分）")
            ->build();

        /*
     * TokenStore can be any of the following
     * DB Persistence - Create an instance of DBStore
     * File Persistence - Create an instance of FileStore
     * Custom Persistence - Create an instance of CustomStore
    */

        /*
    * Create an instance of DBStore.
    * host -> DataBase host name. Default value "localhost"
    * databaseName -> DataBase name. Default  value "zohooauth"
    * userName -> DataBase user name. Default value "root"
    * password -> DataBase password. Default value ""
    * portNumber -> DataBase port number. Default value "3306"
    * tableName -> DataBase table name. Default value "oauthtoken"
    */
        //$tokenstore = (new DBBuilder())->build();

        // $tokenstore = (new DBBuilder())
        //     ->host("hostName")
        //     ->databaseName("dataBaseName")
        //     ->userName("userName")
        //     ->password("password")
        //     ->portNumber("portNumber")
        //     ->tableName("tableName")
        //     ->build();

        // このファイルにリフレッシュトークンが書かれる
        $tokenstore = new FileStore(__DIR__ . "/conf/token.txt");

        // $tokenstore = new CustomStore();

        $autoRefreshFields = false;

        $pickListValidation = false;

        $connectionTimeout = 2; //The number of seconds to wait while trying to connect. Use 0 to wait indefinitely.

        $timeout = 2; //The maximum number of seconds to allow cURL functions to execute.

        $sdkConfig = (new SDKConfigBuilder())
            ->autoRefreshFields($autoRefreshFields)
            ->pickListValidation($pickListValidation)
            // ->sslVerification($enableSSLVerification)
            ->connectionTimeout($connectionTimeout)
            ->timeout($timeout)
            ->build();

        $resourcePath = __DIR__ . "/conf";

        /*
      * Set the following in InitializeBuilder
      * user -> UserSignature instance
      * environment -> Environment instance
      * token -> Token instance
      * store -> TokenStore instance
      * SDKConfig -> SDKConfig instance
      * resourcePath -> resourcePath - A String
      * logger -> Log instance (optional)
      * requestProxy -> RequestProxy instance (optional)
    */
        (new InitializeBuilder())
            ->user($user)
            ->environment($environment)
            ->token($token)
            ->store($tokenstore)
            ->SDKConfig($sdkConfig)
            ->resourcePath($resourcePath)
            ->logger($logger)
            ->initialize();


        //連絡先取得のサンプル。後から消す（何か取得しないと、tokenが書き込まれなかった）
        //Get instance of RecordOperations Class
        $recordOperations = new RecordOperations();
        //Get instance of ParameterMap Class
        $paramInstance = new ParameterMap();
        $headerInstance = new HeaderMap();
        //Call getRecords method
        $response = $recordOperations->getRecords("contacts", $paramInstance, $headerInstance);
        var_dump($response);
    }
}

Initialize::initialize();
```

## 良い感じに使う

サンプルコード集
[https://www.zoho.com/crm/developer/docs/php-sdk/v4/sample-codes.html](https://www.zoho.com/crm/developer/docs/php-sdk/v4/sample-codes.html)

```php
<?php
require_once "vendor/autoload.php";
require_once "initialize.php";
require_once "searchRecords.php";

com\zoho\crm\sample\initializer\Initialize::initialize();
com\zoho\crm\sample\record\Record::searchRecords("contacts");
```