Workato カスタムコネクター開発：アクションの入力項目をレシピ作成時にカスタマイズする方法

# はじめに

Workato では、標準ではサポートされていないアプリケーションに対して、自分でコネクターを作成するコネクター SDK があります。

コネクター作成時に、アクションの入出力の項目の名称や型（スキーマ）を設定しますが、コネクターの作成時にはスキーマを確定できない場合があります。
例えば、DBMS などでは、テーブルの型によって、更新時の入力や検索結果の出力の項目は変わってきます。
そのため、レシピ作成時に入出力のスキーマを変更する必要があります。

ここでは、2024 年 3 月現在で利用できる、レシピ作成時に入力用のスキーマを変更するための方法を説明します。

出力用のスキーマについては[こちらの記事](https://qiita.com/ykkoba/items/94f6d540686f8c03ccb9)を参照してください。

# レシピ作成時に入力用のスキーマを変更するには

Workato ではレシピ作成時にスキーマを変更するために、スキーマデザイナーという機能が提供されています。
コネクター作成時にこのスキーマデザイナーを利用することで、**レシピ作成時にスキーマを変更することが可能**となります。

# 入力項目設定時のスキーマデザイナーの利用方法

この記事では、 Qiita の REST API の呼び出しを例として説明します。

### カスタムコネクターの作成

1. Workato の [Tools] > [Connector SDK] で コネクター SDK を起動します。
![connector_sdk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755136/a389d2c9-01fd-a195-2a3d-fbe8fa5e93c4.png)

1. [New connector] でコネクターを新規作成します。
1. [Get guided from a Workato template] を選択して、[Next] をクリックします。
アプリケーション名に「Qiita」を入力して、[Go to editor] をクリックします。
    
    ここでは認証認可にアクセストークンを使用する方法で Qiita へのコネクタを作成し、Post 用のアクションを定義します。
    ここまでの設定項目の詳細は、本記事では省略します。

    ``` ruby
    {
      title: "Qiita Connector",
      
      connection: {
        fields: [
          {
            name: "token",
            control_type: "string",
            label: "Bearer token",
            optional: false,
          }
        ],
    
        authorization: {
          type: 'custom_auth',
    
          apply: lambda do |connection|
            headers("Authorization": "Bearer #{connection["token"]}")
          end
        },
    
        base_uri: lambda do |connection|
          "https://qiita.com/api/v2/"
        end
      },
    
      test: lambda do |connection|
        get('authenticated_user')
      end,
    
      methods: {},
    
      object_definitions: {},
    
      actions: {
        post_action: {
          title: "Post Action",
          description: "Post Action",
        
          input_fields: lambda do |object_definitions, connection, config_fields|
            []
          end,
          
          execute: lambda do |connection, input|
    
          end,
    
          output_fields: lambda do |object_definitions|
            []
          end,
        }
      },
    
      triggers: {},
    
      pick_lists: {},
    }
    ```


### 入力項目の設定
1. Post アクションの入力用のスキーマを object_definitions ブロックで実施します。
ここでは、呼び出し先の URL と入力スキーマカスタマイズ用のフィールドを定義します。

    ``` ruby
      input_fields: lambda do |object_definitions, connection, config_fields|
        object_definitions["post_action_input"]
      end,
    ```

    ``` ruby
    object_definitions: {
      post_action_input: {
        fields: lambda do |_connection, config_fields|
          [
            {
              name: "url",
              label: "URL",
              optional: false,
            },
            {
              name: "input",
              label: "Input",
              optional: true,
            }
          ]
        end
      }
    }
    ```
    ![input1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755136/0c976d4a-721a-db1e-35e7-9976425c5b34.png)

1. 入力スキーマカスタマイズ用のフィールドを object 型にします。

    ``` ruby
      {
        name: "input",
        label: "Input",
        optional: true,
        sticky: true,
        type: "object",
        properties: [],
      }
    ```

1. properties にスキーマデザイナーを定義します。
スキーマデザイナーは、control_type に schema-designer を指定することで利用可能です。
入出力の項目定義に影響を与えるため、extends_schema に true を設定して、object_definitions 内で config_fields として参照できるようにします。

    ここでの注意点は、スキーマデザイナーはあくまでスキーマ情報を定義するためのもので、定義したスキーマ情報に対する値の入力欄は別途用意する必要があることです。

    ``` ruby
      properties: [
        {
          name: "schema",
          label: "Parameters",
          extends_schema: true,
          add_field_label: "Add parameter",
          control_type: "schema-designer",
          sample_data_type: "json_input",
        },
      ],
    ```

    そのため、この状態では、レシピ作成時にフィールドを追加しても、追加されたフィールドに値を設定するための入力欄は表示されません。
![input2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755136/03836395-106f-49fe-6913-56e5c5a98f80.png)
![input3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755136/fb3a105a-3a57-6fd6-47a8-feae5349a075.png)

1. 入力されたスキーマ情報から入力欄を作成するために、先頭にスキーマ情報を入力欄の定義情報に変換する処理を追加します。
スキーマ情報は、config_fields[オブジェクトの項目名][スキーマデザイナーの項目名] に格納されるため、dig で取得します。
スキーマ情報は文字列なので、parse_json で解析します。

    ``` ruby
      post_action_input: {
        fields: lambda do |_connection, config_fields|
          input_schema = parse_json(config_fields.dig("input", "schema") || "[]")
    ```

    変換された入力情報をもとに入力欄を設定します。
    if 条件を満たさない場合、空の要素ができるため、それを除去するために、配列に対して compact を実行します。

    ``` ruby
    properties: [
        {
          name: "schema",
          label: "Parameters",
          extends_schema: true,
          add_field_label: "Add parameter",
          control_type: "schema-designer",
          sample_data_type: "json_input",
        },
        if input_schema.present?
          { name: "data", type: "object", properties: input_schema }
        end,
      ].compact,
    ```

    ![input4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755136/5bf7e792-3307-5190-b6fb-c8912b834874.png)

1. 入力欄が表示されるようになりましたが、オプションの項目についてはデフォルトで非表示になってしまいます。
非表示にならないよう、入力欄に sticky を設定します。
ネストしたオブジェクトを処理できるように設定用のメソッドを定義し、再帰呼び出しを行います。

    ``` ruby
      methods: {
        make_schema_builder_fields_sticky: lambda do |schema|
          schema.map do |field|
            if field[:properties].present?
              field[:properties] = call("make_schema_builder_fields_sticky", field[:properties])
            elsif field["properties"].present?
              field["properties"] = call("make_schema_builder_fields_sticky", field["properties"])
            end
            field[:sticky] = true

            field
          end
        end,
    ```

    入力情報をコピーして、 sticky を付与します。

    ``` ruby
      fields: lambda do |_connection, config_fields|
        input_schema = parse_json(config_fields.dig("input", "schema") || "[]")

        data_props =
          input_schema.map do |field|
            field
          end

        data_props = call("make_schema_builder_fields_sticky", data_props)
    ```

    入力欄の情報を sticky を付与したものに置き換えます。
    ``` ruby
      { name: "data", type: "object", properties: data_props }
    ```
![input5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755136/7b41fc47-8128-aa95-97c2-7a9c2627727a.png)


### カスタマイズした入力項目を利用したアクション

入力された内容は、input[オブジェクトの項目名][入力欄の項目名] に格納されますので、 dig を利用して取得します。

入力された URL に対して、取得したパラメータで、post メソッドを呼びだします。

``` ruby
  execute: lambda do |connection, input|
    params = input.dig("input", "data") || nil
    url = input['url']

    post(url, params)
  end,
```

### 動作確認

ここでは、動作確認として、Qiita の記事にコメントを追加してみます。

URL にコメント追加のエンドポイントの items/コメントID/comments を指定します。
入力項目は body だけですので、スキーマデザイナーで body の項目を追加し、入力欄で「いいね！」を設定します。

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755136/89afe732-6ab0-9e2d-046d-6e9d2434f9c2.png)

テスト実行すると、記事にコメントが追加されます。

![comment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755136/c847974d-e430-bba5-add5-840d2486a79b.png)

# まとめ

まとめると、以下のようになります。

- Workato のカスタムコネクターでレシピ作成時にスキーマを指定したい場合は、スキーマデザイナーを利用する
- スキーマデザイナー単体では、スキーマの設定しかできないため、値の入力欄の設定が必要


# おわりに

カスタムコネクターで入力項目をレシピ作成時に行いたいケースでは、スキーマデザイナーが利用できます。
入力項目にスキーマデザイナーを使う場合は、合わせて、定義されたスキーマに対応する入力欄を用意する必要があります。

Workatoの導入・導入後の活用などでお困りの場合、Workatoリセラーにご相談する方法もございます。お困りごとがございましたら、認定リセラーの[日立ソリューションズ](https://www.hitachi-solutions.co.jp/rpa/sp/products/workato/?utm_source=sns&utm_medium=qiita&utm_campaign=["203c01feff198315964f"])へ是非ご相談ください。

# 参考リンク

* 株式会社 日立ソリューションズ
    * [Workato ご紹介サイト](https://www.hitachi-solutions.co.jp/rpa/sp/products/workato/?utm_source=sns&utm_medium=qiita&utm_campaign=["203c01feff198315964f"])
* Workato 公式サイト
    * [Workato スキーマ](https://docs.workato.com/ja/developing-connectors/sdk/sdk-reference/schema.html)
* Qiita 公式サイト
    * [Qiita API v2ドキュメント](https://qiita.com/api/v2/docs)