How to ガイド - CLI における test lambda の実行

ここでは、test lambda 関数用 CLI コマンドを実行する方法について簡単に紹介します。

前提条件

  • Workato SDK Gem がインストールされており、実行可能であること。詳細については、入門ガイドを参照してください。
  • 少なくとも認証情報 (接続キー) と test lambda が定義されたコネクターがあること。ここでは以下のサンプルを使用します。
  • 有効な資格情報があること。サンプルコネクターのコードを使用する場合は、そのコネクターの適切な資格情報があることを確認してください。

このガイドで説明する内容

  • 簡易認証シナリオでの test lambda の呼び出し

簡易認証シナリオには、ベーシック認証、API キー、または類似の認証方式が含まれます。この認証方式では、認証時にユーザーが資格情報を提供するだけで済みます。アクセストークンを取得するなどのフォローアップステップを追加する必要はありません。

  • 多段階認証シナリオでの test lambda の呼び出し

多段階認証シナリオでは、ユーザーが入力した情報を使用して、後から別の資格情報を取得します。たとえば、OAuth 2クライアント資格情報フローで認証を行う場合、ユーザーから渡されるクライアント ID とクライアントシークレットを使用して、acquire: lambda でアクセストークンを取得します。

  • OAuth2 (認可コード付与) シナリオでの test lambda の呼び出し

コネクションのタイプが oauth2 に設定されている場合です。

test lambda を実行するべき理由

このコネクションの test lambda は、ユーザーがコネクションのすべての入力項目を指定した後、初めて接続を試行する際に実行されます (OAuth2 (認可コード付与) コネクションを除く)。

さらに、OAuth2 (認可コード付与) を含むすべての認証タイプでは、レシピが最初に開始されたとき、test lambda を呼び出して、そのコネクションがまだ有効であることを確認します。

OAuth2 が初回接続時に test lambda を必要としない理由

OAuth2 (認可コード付与) コネクションは、OAuth2 トークンエンドポイントからトークンが取得されると、Workato により承認されます。有効なトークンが認証サーバーから取得されていれば、そのコネクションは有効と見なされるため、追加の接続テストを実行する必要はありません。

簡易認証シナリオでの test lambda の呼び出し

サンプルコネクター

connector.rb のコードを以下に示します。

ruby
{
  title: 'Chargebee-demo',

  connection: {
    fields: [
      {
        name: 'api_key',
        control_type: 'password',
        hint: 'You can find your API key final change3' \
          "under 'Settings'=>'Configure Chargebee'=>'API Keys and Webhooks'" \
          " in Chargebee's web console.",
        label: 'Your API Key'
      },
      {
        name: 'domain',
        control_type: 'subdomain',
        url: 'chargebee.com'
      }
    ],

    authorization: {
      type: 'basic_auth',  

      apply: lambda do |connection|
        user(connection['api_key'])
      end
    },

    base_uri: lambda do |connection|
      "https://#{connection['domain']}.chargebee.com"
    end
  },

  test: lambda do |_connection|
    get('/api/v2/plans', limit: 1)
  end,
}

settings.yaml.enc に格納された資格情報です。

yaml
api_key: valid_api_key
domain: valid_domain

test lambda の実行

以下のコマンドを実行すると、

shell
$ workato exec test

以下の出力が得られます。

shell
{
  "list": [
    {
      "plan": {
        "id": "cool-product",
        "name": "cool product",
        "price": 10000,
        "period": 2,
        "period_unit": "week",
        "pricing_model": "flat_fee",
        "free_quantity": 0,
        "status": "active",
        "enabled_in_hosted_pages": true,
        "enabled_in_portal": false,
        "addon_applicability": "all",
        "is_shippable": false,
        "updated_at": 1630235299,
        "giftable": false,
        "resource_version": 1630235299389,
        "object": "plan",
        "charge_model": "flat_fee",
        "taxable": true,
        "currency_code": "SGD",
        "show_description_in_invoices": true,
        "show_description_in_quotes": false,
      }
    }
  ],
  "next_offset": "[\"10000\",\"487940\"]"
}

これは定義した test lambda によるそのままの出力ですが、Workato は実際の出力よりも、リクエストが正常に実行されたことに依拠します。

TIP

ここでは他のオプションも使うことができます。たとえば、--verbose を指定すると output_fields の構築時に送信された HTTP リクエストの詳細なログが表示され、--output を指定すると関数の出力が JSON ファイルに保存されます。

多段階認証シナリオでの test lambda の呼び出し

サンプルコネクター - 多段階認証

connector.rb のコードを以下に示します。

ruby
{
    name: "Percolate",
    connection: {
      fields: [
        { name: "client_id",
          optional: false,
          hint: "To create client ID, the system admin or manager can click " \
          "<a href='https://percolate.com/app/settings/developer/apps/new' " \
          "target='_blank'>here</a> to register a new client application." },
        { name: "client_secret",
          control_type: "password",
          optional: false,
          hint: "To create client secret, the system admin or manager can click" \
          " <a href='https://percolate.com/app/settings/developer/apps/new' " \
          "target='_blank'>here</a> to register a new client application." },
        { name: "environment",
          optional: false,
          control_type: "select",
          pick_list: [%w[Production production], %w[Sandbox sandbox],
                      %w[Internal internal]] }
      ],

      authorization: {
        type: "custom_auth",

        acquire: lambda do |connection|
          hash = Base64.encode64("client:#{connection['client_id']}:#{connection['client_secret']}").gsub("\n", "")
          post("https://percolate.com/auth/v5/token/")
            .payload(grant_type: "client_credentials")
            .headers(Authorization: "Basic " + hash)
            .request_format_www_form_urlencoded
            .after_response do |_code, body, headers|
              body["headers"] = headers
              body
            end
        end,

        detect_on: [401, 403],

        refresh_on: [401, 403],

        apply: lambda do |connection|
          if current_url.include?("https://percolate.com")
            headers(Authorization: "Bearer #{connection['access_token']}")
          end
        end
      },

      base_uri: lambda do |_connection|
        "https://percolate.com"
      end
    },

    test: lambda do |_connection|
      get("/api/v5/me")
    end,
}

settings.yaml.enc に格納された資格情報です。

yaml
client_id: valid_client_id
client_secret: valid_client_secret
environment: production

test lambda の実行

次のコマンドを実行すると、

shell
workato exec test --verbose

次のような出力が得られます。

shell
SETTINGS
{
  "client_id": "valid_client_id",
  "client_secret": "valid_client_secret",
  "environment": "production",
}
INPUT
{
}

RestClient.get "https://percolate.com/api/v5/me", "Accept"=>"application/json", "Accept-Encoding"=>"gzip, deflate", "Authorization"=>"Bearer ", "User-Agent"=>"rest-client/2.0.2 (darwin19.6.0 x86_64) ruby/2.4.10p364"
# => 401 Unauthorized | application/json 65 bytes         
Progress: |=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=|
RestClient.post "https://percolate.com/auth/v5/token/", "grant_type=client_credentials", "Accept"=>"application/json", "Accept-Encoding"=>"gzip, deflate", "Authorization"=>"Basic ", "Content-Length"=>"29", "Content-Type"=>"application/x-www-form-urlencoded", "User-Agent"=>"rest-client/2.0.2 (darwin19.6.0 x86_64) ruby/2.4.10p364"
# => 200 OK | application/json 25 bytes                                       
Progress: |=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=|

Refresh token triggered on response "401 Unauthorized"
Update settings file with new connection attributes? (Yes or No)

まずこの出力結果では、コネクションの test lambda (api/v5/me エンドポイント) が 401 レスポンスを返したことから、設定ファイルに access_token が存在しないことがわかります。

これにより、acquire lambda (auth/v5/token エンドポイント) がトリガーされます。この acquire lambda は、認証エンドポイントへの POST API 呼び出しです。この場合、acquire ブロックの出力が connection ハッシュにマージされます。これは、refresh_on シグナルの場合にのみ acquire lambda が呼び出される、Workato プラットフォームでの動作と同じです。

現在のアクセストークンの有効期限が切れたら、acquire lambda の refresh_on 属性がトリガーされ、新しいアクセストークンが取得されます。これは、コネクションの test lambda など、lambda 関数が呼び出されるたびにトリガーされます。

最後に、Gem により設定ファイルを上書きする許可を求められます。この設定ファイルは、Workato プラットフォームの connection ハッシュと同じ役割を担います。「Yes」と入力すると、acquire lambda の出力で設定ファイルが更新されます。

shell
Update settings file with new connection attributes? (Yes or No) Yes
RestClient.get "https://percolate.com/api/v5/me", "Accept"=>"application/json", "Accept-Encoding"=>"gzip, deflate", "Authorization"=>"Bearer example_token", "User-Agent"=>"rest-client/2.0.2 (darwin19.6.0 x86_64) ruby/2.4.10p364"
# => 200 OK | application/json 65 bytes         
Progress: |=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=|

OUTPUT
# Output of the test lambda

settings.yaml.enc の資格情報が更新されます。

yaml
client_id: valid_client_id
client_secret: valid_client_secret
environment: production
id: token:example_token
expires_in: 2592000
updated_at: '2021-08-30T14:54:35+00:00'
user_id: user:130135
grant_id: grant:1216779461986395763
access_token: example_token
token_type: bearer

OAuth2 (認可コード付与) シナリオでの test lambda の呼び出し

認可コード付与フローについて、Workato Gem では、workato oauth2 コマンドを使用して OAuth2 フローをエミュレートすることができます。この手法により、エンドユーザーにとって OAuth2 がどのような操作になるのかを、すばやくデバッグして理解することができます。

サンプルコネクター - OAuth 2コネクター

connector.rb のコードを以下に示します。

ruby
{
  title: 'TrackVia',
  connection: {
    fields: [
      {
        name: 'custom_domain',
        control_type: 'subdomain',
        label: 'TrackVia subdomain',
        hint: 'Enter your TrackVia subdomain. e.g. customdomain.trackvia.com. By default, <b>go.trackvia.com</b> will be used.',
        optional: 'true'
      },
      {
        name: 'account_id',
        control_type: :number,
        label: 'Account ID',
        hint: 'Specify the account to connect to',
        optional: true
      },
      {
        name: 'client_id',
        control_type: :text,
        label: 'TrackVia App Client ID',
        hint: 'Enter the Client ID of your own OAuth app registered on TrackVia',
        optional: 'false'
      },
      {
        name: 'client_secret',
        control_type: :text,
        label: 'TrackVia App Client secret',
        hint: 'Enter the Client secret of your own OAuth app registered on TrackVia',
        optional: 'false'
      }
    ],

    authorization: {
      type: 'oauth2',

      authorization_url: lambda { |connection|
        "https://#{connection['custom_domain'].presence || 'go.trackvia.com'}/oauth/authorize?response_type=code"
      },

      acquire: lambda do |connection, auth_code, redirect_uri|
        url = "https://#{connection['custom_domain'].presence || 'go.trackvia.com'}"
        response = post("#{url}/oauth/token").payload(
          redirect_uri: redirect_uri,
          grant_type: 'authorization_code',
          code: auth_code,
          client_id: connection['client_id'],
          client_secret: connection['client_secret']
        ).request_format_www_form_urlencoded
        user_key = get("#{url}/3scale/openapiapps").params(access_token: response['access_token']).dig(0, 'userKey')
        [
          response,
          nil,
          {
            user_key: user_key
          }
        ]
      end,

      refresh: lambda do |connection, refresh_token|
        url = "https://#{connection['custom_domain'].presence || 'go.trackvia.com'}"
        post("#{url}/oauth/token").payload(
          client_id: connection['client_id'],
          client_secret: connection['client_secret'],
          grant_type: 'refresh_token',
          refresh_token: refresh_token
        ).request_format_www_form_urlencoded
      end,

      refresh_on: [401, 403],

      apply: lambda { |connection, access_token|
        params(user_key: connection['user_key'])
        headers(Authorization: "Bearer #{access_token}")
        headers('account-id': connection['account_id']) if connection['account_id'].present?
      }
    },

    base_uri: lambda do |connection|
      if connection['custom_domain'].presence
        "https://#{connection['custom_domain']}/openapi/"
      else
        "https://go.trackvia.com/openapi/"
      end
    end
  },

  test: lambda do |connection|
    get('views') 
  end,
}

settings.yaml.enc に格納された資格情報です。

yaml
client_id: valid_client_id
client_secret: valid_client_secret

ここで以下のコマンドを実行して、ブラウザのポップアップを含めた OAuth2 認可コードフローを確認することができます。OAuth2 フローの詳細なロギングを有効にするには、--verbose を指定します。

shell
workato oauth2 --verbose

これにより、ブラウザのポップアップから authorization_url の出力 URL に至るまで、フロー全体がシミュレートされ、コールバック URL への認可コードに加えて、token_url lambda や acquire lambda に含まれる後続の呼び出しへの認可コードが受信されます。このフローの最後に、settings.yaml ファイルが、OAuth2 フローから受信した最新の資格情報で更新されます。

SDK Gem Oauth2 フローWorkato 上で OAuth2 フローをエミュレートする SDK Gem

このフローが終わると、settings.yaml.enc ファイルが最新の資格情報で更新されているはずです。

yaml
client_id: valid_client_id
client_secret: valid_client_secret
user_key: valid_user_key
tokenType: bearer
expires_in: 299
expiration: '2021-10-19T15:36:39.221+0000'
scope:
- trust
- read
- write
apiVersion: '22.18'
access_token: valid_access_token
refresh_token: valid_refresh_token

test lambda の実行

このフローの実行が成功したら、同じ workato exec test コマンドを使用して、トークンがリクエストで正しく適用されているかどうかを確認できます。

トークンを受信したタイミングによっては、アクセストークンを更新するかどうか確認する Gem の中間コマンドが表示される場合もあります (有効期限切れの場合)。これが行われるのは、HTTP リクエストが実行され、そのレスポンスが refresh_on ブロックをトリガーする場合です。[Yes] を選択すると、Gem は最新の資格情報で設定ファイルを更新します。

shell
$ workato exec test --verbose

次のような出力が得られます。

shell
SETTINGS
{
  "client_id": "valid_client_id",
  "client_secret": "valid_client_secret",
  "user_key": "valid_user_key",
  "tokenType": "bearer",
  "expires_in": "299",
  "expiration": "2021-10-19T15:36:39.221+0000",
  "scope": ["trust", "read", "write"],
  "apiVersion": "2.18",
  "access_token": "valid_access_token",
  "refresh_token": "valid_refresh_token"
}
INPUT
{
}

RestClient.get "https://go.trackvia.com/openapi/views", "Accept"=>"application/json", "Accept-Encoding"=>"gzip, deflate", "Authorization"=>"Bearer valid_access_token", "User-Agent"=>"rest-client/2.0.2 (darwin19.6.0 x86_64) ruby/2.4.10p364"
# => 401 Unauthorized | application/json 65 bytes         
Progress: |=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=|
RestClient.post "https://go.trackvia.com/oauth/token", "grant_type"=>"client_credentials", "Accept"=>"application/json", "Accept-Encoding"=>"gzip, deflate", "refresh_token"=>"valid_refresh_token", "Content-Length"=>"29", "Content-Type"=>"application/x-www-form-urlencoded", "User-Agent"=>"rest-client/2.0.2 (darwin19.6.0 x86_64) ruby/2.4.10p364"
# => 200 OK | application/json 25 bytes                                       
Progress: |=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=|

Refresh token triggered on response "401 Unauthorized"
Updated settings file with new connection attributes? (Yes or No)

まずこの出力結果では、コネクションの test lambda (openapi/views エンドポイント) が 401 レスポンスを返したことから、設定ファイルに有効な access_token が存在しないことがわかります。アクセストークンの有効期限が切れている可能性があります。

これにより、acquire lambda (/oauth/token エンドポイント) がトリガーされます。この acquire lambda は、認証エンドポイントへの POST API 呼び出しです。この場合、acquire ブロックの出力が connection ハッシュにマージされます。これは、refresh_on シグナルの場合にのみ acquire lambda が呼び出される、Workato プラットフォームでの動作と同じです。

現在のアクセストークンの有効期限が切れたら、acquire lambda の refresh_on 属性がトリガーされ、新しいアクセストークンが取得されます。これは、コネクションの test lambda など、lambda 関数が呼び出されるたびにトリガーされます。

最後に、Gem により設定ファイルを上書きする許可を求められます。この設定ファイルは、Workato プラットフォームの connection ハッシュと同じ役割を担います。「Yes」と入力すると、acquire lambda の出力で設定ファイルが更新されます。

shell
Updated settings file with new connection attributes? (Yes or No) Yes
RestClient.get "https://go.trackvia.com/openapi/views", "Accept"=>"application/json", "Accept-Encoding"=>"gzip, deflate", "Authorization"=>"Bearer new_valid_access_token", "User-Agent"=>"rest-client/2.0.2 (darwin19.6.0 x86_64) ruby/2.4.10p364"
# => 200 OK | application/json 65 bytes                
Progress: |=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=|

OUTPUT
# Output of the test lambda

settings.yaml.enc の資格情報が更新されます。

yaml
client_id: valid_client_id
client_secret: valid_client_secret
user_key: valid_user_key
tokenType: bearer
expires_in: 299
expiration: '2021-10-19T15:41:39.221+0000'
scope:
- trust
- read
- write
apiVersion: '22.18'
access_token: new_valid_access_token
refresh_token: new_valid_refresh_token

注 :

workato exec を使用して、acquirerefresh などの lambda を authorization ハッシュで実行することもできます。 しかしながら、settings.yaml ファイルの自動更新を行う workato exec testworkato oauth2 を使用することを強くお勧めします。

Last updated: