6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LookerAdvent Calendar 2020

Day 20

Looker Custom Actionを作成する

Last updated at Posted at 2020-12-19
当エントリは2020年アドベントカレンダー『Looker Advent Calendar 2020』の20日目のエントリとなります。

こんにちは。株式会社電通国際情報サービスのkumakuraです。今回はLookerの外部連携機能であるActionについて記事を書いていこうと思います。また、実際に作成したMicrosoft Teamsとビジネス版LINE「LINE WORKS」のActionについても記事を作成しましたので、そちらもご覧になっていただければと思います。

#目次
1. Action/Action Hubとは
2. Custom Actionの開発方法
3. 公式フレームワーク/Action APIで開発する
4. LookerインスタンスにAction Hubを登録する
5. Microsoft Teams/LINE WORKSのActionを作成してみました
6. おわりに

#1. Action/Action Hubとは

BIツールLookerでは分析して得た結果や条件に応じて、Action Hubと呼ばれるサーバを経由して外部サービスにデータを連携することができます。
Looker内ではそれら外部サービス連携機能を**Action**と呼びます。

Looker公式でTwilioやSlackといったActionが数十種類公開されており、Lookerインスタンス内で有効にするだけで簡単に利用できます。

ただ、「一覧にないサービスと連携したい!」「独自のシステムと連携したい!」
といった場合は**独自にAction(以降Custom Action)**を開発することも可能です。

#2. Custom Actionの開発方法

Custom Actionを利用したい!となった場合、大きく分けて3つ方法があります。

  1. 公式が提供しているNode.jsのフレームワークを用いて、Lookerのgithubにcontributeする
    Looker公式のAction HubはGithub上で公開されております。
    アクションを作成し、プルリクエストを送り、Lookerからレビュー/検査を通ったアクションは全Lookerユーザが利用できる形で公開され、公式のActionの一つとなります。

  2. 公式が提供しているNode.jsのフレームワークを使い、プライベートなAction Hubを建てる
    全ユーザに公開したくない場合は独自にAction Hubサーバを用意し、Lookerインスタンス上で登録することでAction Hubとして利用することが出来ます。
    Node.jsのフレームワークのテンプレートも公開されているので利用することで、簡単に開発が可能です。

  3. Action APIを使用して、プライべートなAction Hubを建てる
    公式のフレームワークを利用せずに、Action APIと呼ばれるエンドポイントを直接実装することで、Action Hubサーバを建てることもできます。

 
以下はActionを開発し、Lookerインスタンスで利用するまでのワークフローです。
looker action flow
引用:https://docs.looker.com/sharing-and-publishing/action-hub#adding_user_attributes_to_custom_actions

1が上のフローにおける*"Build a Custom Action, Publish to the Looker Action Hub Server"に該当し、2、3が"Build a Custom Action, Publish to Private Action Hub Server"*に該当します。

1、2の場合、フレームワークはTypescriptで書かれているので準拠する必要がありますが、3の場合、APIを叩くことができればどの言語でも構いません。
また、フレームワーク内部でもAction APIを利用しており、どちらで開発しても作成できる機能に違いはありませんので、好きな方法で開発していただければと思います。

#3. 公式フレームワーク/Action APIで開発する
2章で紹介したように、Custom Actionを利用する場合、「公式フレームワークを利用する」ケースと「Action APIを利用する」ケースの二つが存在します。3章ではそれぞれ簡単に開発方法について説明していきたいと思います。
なお、公式フレームワークはAction APIをラップしたような関係であるため、Actionを定義するときに必要なパラメータはほぼ同じなので、説明の都合上、Action APIの方から説明いたします。

##3.1. Action API

Action APIとはLookerからのアクションを受け入れるIncoming WebhookのようなAPIです。
LookerインスタンスからActionに関係する操作を行ったとき、操作に応じてそれぞれ指定のエンドポイントにリクエストが送られます。サーバ側としてはリクエストに応じて特定のレスポンスを返す必要があります。
エンドポイントは基本的にlistexecuteform等になります。
それらエンドポイントを搭載したサーバを用意し、Lookerインスタンスに登録することでAction Hubとして利用することが可能になります。

次にlistexecuteformでどのようなHTTPリクエストが発生し、どのようなHTTPレスポンスを返す必要があるのかサンプルを交えながら説明して行きます。
※今回、サンプルとして取り上げた項目以外にも多くの設定項目がありますので、公式のドキュメントをご参考ください

listエンドポイント

Actionをインスタンスに設定する時や、実際にセル、クエリ(Explore,Look)、ダッシュボードからActionを実行する時に空のPOSTが送られるエンドポイントです。
レスポンスとしてActionの定義情報を返す必要があります。
また、Action"HUB"と呼ばれるように一つのエンドポイントで複数のActionを提供することが出来ます。
後述する executeエンドポイント/formエンドポイント 先などもこの際に定義します。

Sample HTTPレスポンス

{
    "label": "Action hub label",
    "integrations": [
      {
        "name": "action_name",
        "label": "Action Label",
        "supported_action_types": ["cell", "query", "dashboard"],
        "url": "https://XXXX/action/execute",
        "form_url": "https://XXXX/action/form",
        "icon_data_uri": "data:imageXXXXXX",
        "required_fields": [
          {
            "tag": "test",
          },
        ],
        "params": [
          {
            "name": "param_name",
            "label": "param label",
            "required": true,
          },
        ],
        "supported_formats": ["txt", "wysiwyg_png"],
        "supported_visualization_formattings": ["apply"],
        "supported_download_settings": ["url"],
      },
    ],
}

####Sampleの説明

キー 説明
supported_action_types Actionを実行できるフォーマットを定義します。
cellの場合は1つの値から、queryの場合はexplore/viewから、dashboradの場合はダッシュボードから
Actionを実行することができます。
url 後述するexecuteエンドポイントを指定します。
form_url 後述するformエンドポイントを指定します。
icon_data_uri Actionの一覧画面に表示されるアイコンです。Data URI形式で定義します。
required_fields supported_action_typeにcellが指定されている場合、
required_fieldsで定義したtagが付けられているdimension/fieldのみActionを実行することができます。
params Actionを有効化する際にユーザに入力させる項目を定義します。
アクセストークンといったAction全体で使用したい定義情報をユーザに入力させる目的で利用されます。
supported_formats Actionが実行された際にどの形式で分析データを送るかを定義できます。
queryの場合はcsv、json、txt、html等から選択でき、dashboardの場合は画像形式が選択できます。

formエンドポイント

Actionを選択したときに空のPOSTが送られるエンドポイントで、上記のListエンドポイントでActionを定義する際にform_urlで指定したエンドポイントとなります。
Actionを利用する際にユーザに入力させるフォーム情報を返す必要があります。

Sample HTTPレスポンス

[
    {
      "name": "form_name",
      "label": "form",
      "description": "form description",
      "type": "textarea",
      "required": true,
    },
]

Sampleの説明

キー 説明
type ユーザに入力させるフォームの形式を選択できます。"text","textarea","select"から選択できます。
"select"とはセレクトボックス形式のことで、選択した場合_options_キーを追加し、セレクトボックスの値を定義する必要があります。
複数選択は指定できません
required 項目を必須にすることができます

executeエンドポイント

Actionが実行する時に選択したセル、クエリ、ダッシュボードの情報がPOSTで送られるエンドポイントです。
このエンドポイントから受け取ったデータを元に具体的な処理を行います。

Sample HTTPリクエスト(CELLの場合)


{
  type: 'cell',
  scheduled_plan: null,
  attachment: null,
  data: {
    param:'param',
    value:'value'
  },
  form_params: { form: 'form' },
}

Sampleの説明

  • dataにはユーザがActionを有効化した際に入力した項目です。
  • valueは選択したセルの値が入ります。
  • form_paramsはActionを実行する際にユーザが入力したフォームの値です。

Sample HTTPリクエスト(QUERYの場合)

{
  type: 'query',
  scheduled_plan: {
    scheduled_plan_id: 19,
    title: 'sample title',
    type: 'Query',
    url:
      'https://lookerinstance.jp.looker.com/explore/model/query',
    query_id: 1341,
    query: {
      id: 1341,
      view: 'view name',
      fields: [Array],
      pivots: null,
      fill_fields: null,
      filters: null,
      filter_expression: null,
      sorts: [Array],
      limit: '10',
      column_limit: null,
      total: null,
      row_total: null,
      subtotals: null,
      vis_config: {},
      filter_config: null,
      visible_ui_sections: null,
      slug: 'xxxxxxx',
      dynamic_fields: '[]',
      client_id: 'xxxxxxx',
      share_url: 'https://lookerinstance.jp.looker.com/x/XXXXXX',
      expanded_share_url:
        'https://lookerinstance.jp.looker.com/explore/model/XXXXXX',
      url:'/explore/model/XXXXXX',
      query_timezone: 'America/Los_Angeles',
      runtime: null,
      has_table_calculations: false,
      model: 'model',
    },
    filters_differ_from_look: null,
    download_url:
    'https://lookerinstance.jp.looker.com/download/XXXXXX',
  },
  attachment: null,
  data: {
    param:
      'param',
  },
  form_params: { message: 'test' },
}

Sampleの説明

  • Listエンドポイントで  supported_download_settingsurlを設定していた場合、download_urlパラメータに一度のみ有効なデータのダウンロードリンクが添付されますが、supported_download_settingsに何も設定していない場合はattachmentパラメータにデータの情報がそのまま添付されます

    - attachment以下にデータが入る例(textの場合)
    
      attachment: {
        mimetype: 'text/plain',
        extension: 'txt',
        data:'xxxxx',
      }
    

Sample HTTPリクエスト(DASHBOARDの場合)

{
  type: 'dashboard',
  scheduled_plan: {
    scheduled_plan_id: 99,
    title: 'Sample Dashboard',
    type: 'Dashboard',
    url:
      'https://lookerinstance.jp.looker.com/dashboards/?XXXXXXXX',
    query_id: null,
    query: null,
    filters_differ_from_look: null,
    download_url: null,
  },
  attachment: {
    mimetype: 'image/png;base64',
    extension: 'png',
    data: 'XXXXXXXXXXXXXXXXXXXXXXXXXX',
  },
  data: {
    param:'param',
  },
  form_params: { form: 'form' },
}

Sampleの説明

  • attachmentパラメータの中にbase64でファイルが添付されます。(上記の例はpng)

##3.2. Looker公式Node.jsフレームワーク
「公式としてCutsom Actionを公開する」または「公式のフレームワークのテンプレートを用いて開発する」場合は以下の手順に則っていただければと思います。

1.フォルダを配置

公式のgithubからフォークしていただくか、テンプレートをインストールしていただき、
actions > src > actions 配下に追加したいActionのフォルダを追加します。
[参考] https://github.com/looker/actions/tree/master/src/actions

2.フォルダの配下にコードを配置します。

フォルダの配下にActionを実装したクラスを配置します。下記サンプルコードを見ていただけると分かるかと思いますが、Action APIのlistexecuteformを1つにまとめたようなクラスとなっております。

Sample Code
import * as Hub from "../../hub";

export class SampleAction extends Hub.Action {
  name = "action_name";
  label = "action_label";
  iconName = "folder/sample.png";
  description = "sample description";
  supportedActionTypes = [Hub.ActionType.Query];
  supportedFormats = [Hub.ActionFormat.Csv];
  supportedFormattings = [Hub.ActionFormatting.Unformatted];
  supportedDownloadSettings = [Hub.ActionDownloadSettings.Push];
  requiredFields = [];
  params = [];

  async execute(req: Hub.ActionRequest) {

    //
    // 具体的な処理
    //

    return new Hub.ActionResponse(response);
  }

  async form(req: Hub.ActionRequest) {
    const form = new Hub.ActionForm();
    form.fields = [];
    form.fields.push({
      label: "form label",
      name: "form_name",
      required: true,
      type: "string",
    });

    return form;
  }
}

Hub.addAction(new TeamsAction());

内容は、細かな違いはありますが、Action APIで定義した内容と似ていますね。

3.(公式にContributeする場合)Testクラスを作成します

公式にContributeする場合Testクラスを作成する必要があります。
公式フレームワークで採用しているテストのライブラリはmocha+chai+sinonとなっております。

4.indexの編集

actions > src > index.tsactions > test > test.ts
にそれぞれ作成したAction/Testクラスのソースコードのパスを通します。

以上でActionの実装は完了なのですが、注意点として公式のNode.jsのフレームワーク利用したAction HubをLookerインスタンスに登録する際、APIキーを作成し、環境変数として組み込む必要があります。
詳細はドキュメントをご確認ください

#4. LookerインスタンスにAction Hubを登録する

3.でソースコードが完成したら、任意の環境にデプロイしましょう。
公式ではHerokuで説明されておりますが、例えばAWS上で構築していただいても全く問題ありません。

Action Hubサーバをデプロイしたら、Lookerインスタンスに登録しましょう!
管理タブからActionを選択肢、[Add Action Button]を選択し、作成したAction HubのURLを入力することでCustom Actionを利用できるようになります。
Action APIを利用している場合はここにlistエンドポイントのURLを入力してください。
(公式フレームワークを使用する場合、作成されたAPIキーをAuthorization Tokenに入力する必要があります。)
Looker Page.png

以上が簡単ではありましたがAction Hubの構築方法となります。

#5. Microsoft Teams/LINE WORKSのActionを作成してみました
(量が多くなってしまうので、記事を分割しました)
前述のLookerが提供しているNode.jsのフレームワークを用いてMicrosoft TeamsのActionとAction APIを用いてLINE WORKSのActionを作成してみました。

具体的な実装例なども併せて紹介しておりますので、ご覧ください!

#6. おわりに
今回は簡単にAction Hubの構築方法について記載してきましたが、他にもAction Hubには多くの機能があり、OAuthを用いてユーザ個別の処理を実装したり、formをユーザの入力を元に動的に変更させたり色々できますのでドキュメントを是非ご覧ください。

公式のActionとして公開する場合、全Lookerユーザが利用するので汎用的な設計を心がける必要がありますが、独自でAction Hubサーバを立てる場合、要件に特化した連携機能を作成することができますので、是非皆さんもAction機能を開発してみて、Lookerをデータプラットフォームとして有効活用していきましょう!
ここまで読んでいただきありがとうございました。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?