TECHSCORE BLOG

クラウドCRMを提供するシナジーマーケティングのエンジニアブログです。

Node-REDでSynergy!のAPIを使ってみる

弊社のSynergy!は、Synergy!データベースAPIと呼ばれるデータ操作を外部のシステムから行うためのAPIを提供しています。参考リンク
このAPIを使うことで、より柔軟にデータの操作や加工が可能になるのですが、その「外部のシステム」を用意するのはシステム開発に詳しい人でないと難しいところでもあります。

プログラムコードを書かない、もしくは書くとしても最小限で済むようなローコードのツールがあれば、Synergy!データベースAPIを簡単に使えるのでは?
そんな考えから、何かいい感じのものがないかと探し、見つかったものが今回紹介するNode-REDとなります。

中西 崇彰(ナカニシ タカアキ)
Synergy!のQA担当だったり、Webアプリケーションの保守だったりと幅広いことをやってます。
今一番使いたい忍術は影分身の術


簡単にNode-REDの紹介

Node-RED日本ユーザ会の公式サイトに概要が記載されています。

Node-REDはフローベースドプログラミング(flow-based programming)ツールであり、元はIBM Emerging Technology Servicesチームによって開発され、JS Foundation配下のプロジェクトを経て、2019年3月よりNode.js FoundationとJS Foundationが合併して設立されたOpenJS Foundationにホストされています。

元はIoT用にIBMによって開発されたもので、現在はOSSとしてOpenJS Foundationによって開発が続いています。 OSSであること、基盤がNode.jsであるためJavaScriptが書ける人であれば参入しやすそうであることの2点が触ってみようと思ったきっかけです。

実際の画面

今回は検証用ということで、ローカル環境でDockerを使って動かしました。 公式から手順が用意されているので、迷うことなく実行できました。

実際の画面は上の画像のような感じです。 ブラウザ上で利用でき、左側にあるノードと呼ばれるアイコンを組み合わせて任意の処理(=フロー)を作成できます。 各ノードの説明は Node-RED上で閲覧できる他、公式サイトで作成例も紹介されています。

ノードは初期からあるものに加えて、他の方が作成したノードを追加したり、自作したりといったことが可能です。 その方法も公式サイトに記載があるので、無償のソフトウェアとしてはかなり資料が充実していると思います。

Synergy!データベースAPIでデータを取得

今回はSynergy!データベースAPIの基本的なフローである、以下の流れを作ってみようと思います。

  1. 事前に作成しておいたアクセスキーとシークレットでアクセストークンを発行する
  2. そのアクセストークンを使ってAPIのリクエストを送り、Synergy!内にあるデータを取得する

まずはアクセストークンを発行し、そのトークンを一時的に保存するフローを作ります。

アクセストークン取得

アクセストークンを取得するための工程は、大まかに以下のようになります。

■工程

  1. Synergy!管理画面にてSynergy!データベースAPIのアクセスキーとシークレットを作成する
  2. アクセスキー、シークレットをbase64でエンコードする
  3. 2で作成したものをAuthorizationヘッダーに入れ、アクセストークンを取得するためのAPIエンドポイントへPOSTリクエストを送る
  4. 3のレスポンスをもとにアクセストークンが取得できるため、それを再利用できる変数などに保存する

今回はアクセストークンを取得し、それを再利用可能にする変数に入れることを目標とします。
そのため、1、2は事前に準備しておき、3、4を実現するフローを作成します。

アクセストークンを取得し、変数に格納するためのフローは以下のようになりました。

それぞれのノードの詳細を上記画像の番号順で記載します。 フローの処理順と一部異なっていますが、こちらはフローを作成するにあたってノードを追加した順番になっていますので、その考え方も含めて説明できればと思います。

http requestノード(①)

  • 今回の肝となるノードで、HTTPリクエストを実行できる
  • POSTの場合、msg.payloadで渡されたものをリクエストボディにして実行するが、その内容は後述の inject ノードで簡単に定義することが可能
  • ヘッダ部分にAuthorizationとContent-Typeを定義。AuthorizationにはアクセスキーとシークレットをBase64でエンコードしたものを記載(工程2で作成したもの)
    • 画像ではXXXX...とマスキングしている
    • よりセキュリティを意識するのであれば直接記載ではなく、ファイルなどから渡せるようにしたほうがよさそう

今回の目標を実現するには、まずHTTPリクエストを送ることができる、といったことが必要になります。 そのため、http request ノードを設定しています。 次に、このhttp request ノードにどうやってデータを渡すのか。さらにリクエストの結果をどうやって変数に格納するのかを考えます。

injectノード(②)

  • 文字通り何かを注入(inject)するためのノード
  • 実行タイミングや繰り返し間隔も設定できるので、実質cronみたいな使い方ができる
  • http requestノードの前段に置くことで、次のHTTPリクエストのリクエストボディを定義できる

この injectノードを使うことでリクエストボディを定義することが可能になり、http request ノードと合わせて工程3が実現できました。 ただし、このままだとhttp request ノードのリクエストの結果(=レスポンス)がそのままとなるため、受け取ったレスポンスを加工し変数に格納するといった工程が必要になります。 そのために利用したのが次の change ノードになります。

changeノード(③)

  • 前段のノードの結果(msg.payload)を加工するノード
  • 例では前段の結果から access_token の部分だけ抜き出し、次のdebugノードに渡すための msg.payload とフロー全体で使うための変数 flow.access_token に代入している

Synergy!データベースAPIのアクセストークン取得リクエストが成功すると、以下のようなレスポンスが返ってきます。

{
  "access_token": "{Access Token}",
  "expires_in": 3599,
  "scope": "db:apidefinition:design db:openapi:read db:record:execute",
  "token_type": "bearer"
}

ここで、http request ノードの出力形式を「JSONオブジェクト」にしておくと、JSONの各要素を呼び出すように msg.payloadから呼び出すことが可能になります。 今回実施したいことは「アクセストークンを変数に格納する」ということなので、msg.payload.access_tokenを対象の値に選択し、代入先として flow.access_token と指定することで、フロー全体でアクセストークンが利用可能になります。 今回はそれに加えて、次のdebugノードで意図通り取得できているか確認したかったため、同じ msg.payload.access_token を msg.payload にも代入しています。

また、今回は実装していませんが、上記 expires_inで表示されるアクセストークンの有効期限を使って、有効期限間近もしくは超過した時点でアクセストークンを再取得する、といった自動化もできそうです。

debugノード(④)

  • 指定した対象をデバッグウィンドウやシステムコンソールなどに表示できるノード

実際のところ、今回のフローができるまでそこそこの回数、このdebugノードにお世話になりました。 1つの実装を変えてdebugノードをくっつけて出力を確認する、といった流れが簡単にできるのもこういったローコードのツールの利点だと思います。

フローが作成できたら保存し、手動実行の場合は上記画像の赤丸で囲った部分をクリックすると動きます。 今回はdebugノードを付けているので、実行結果がデバッグウィンドウに表示されるようになっています。

実行結果

  • 画像ではマスクしているが、実際に文字列(=トークン)が表示されている
  • デバッグウインドウの表示限界で後ろが省略されているが、changeノードで代入している変数にはそのままの文字列が入っている

これでAPIの実行に必要なアクセストークンが取得できたので、次はAPIの実行フローを作成します。

API実行

APIを実行、と言ってもSynergy!データベースAPIには様々なAPIを提供しています。 今回はgetRecordを使い、Synergy!IDから顧客マスタに存在するデータを取得してみます。

主な工程は以下になります。

■工程

  1. API定義登録をする(初回のみ)
  2. 定義を行ったAPIに対し、有効期限が切れていないアクセストークンをヘッダーに含め、APIエンドポイントにGETリクエストを送る。

今回は取得したアクセストークンが利用できるのか、ということを確かめたいので、工程2をフローにしてみます。

今回のフローは以下のような形になりました。

こちらも先ほどのAPIトークン取得フローと同じく、番号順=ノードを追加した順番となっていますので、その順番で以下に詳細を記載します。

http requestノード(①)

  • またもや主役のノード
  • 今回はPOSTではなく、GETリクエストを送るものとして利用

getRecordのAPIエンドポイントは以下になります。

https://db.paas.crmstyle.com/apis/record.database/v1/accounts/{accountCode}/
{name}/records/{id}
  • accoutCode はSynergy!のアカウントごとに異なります
  • name が1で定義登録をしたAPIの名前です
  • id はSynergy!ID(=Synergy!で利用する一意な番号)を入力します

実際の運用などを考えると、accountCode、nameは固定でよさそうですが、id は固定ではなく可変であることが想定されます。 そのため、今回は id を別のものから渡す、といったことを試してみました。

injectノード(②)

ここでは msg.payloadに上記で作成したアクセストークンが格納された変数、flow.access_token を設定し、もう一つ msg.synergyidを定義し、そこに対象となるidの 1 を設定しています。

これを用いると、http request ノードの リクエスト先のURL を動的に変更させることが可能になります。

https://db.paas.crmstyle.com/apis/record.database/v1/accounts/xxxx/xxxx/records/{{{synergyid}}}

※アカウントコードとAPI名はxxxxと記載しています

上記のように書くことで msg.synergyid に設定した値が展開され、

https://db.paas.crmstyle.com/apis/record.database/v1/accounts/xxxx/xxxx/records/1

というURLになります。

さて、これでフローはできたと思いたいところですが、実はもう一つ壁があります。 それは アクセストークンの渡し方 です。

各APIに対し、アクセストークンは以下のようなヘッダーを設定する必要があります。

Authorization: Bearer ${ACCESS_TOKEN}

Autorization は http request ノードで選択可能ですが、アクセストークンの前にある Bearer の文字列が最後まで実装をどうしようか悩んだポイントです。

URLにidを展開したときと同じように

Bearer {{{payload}}}

で行けるかなと思いきやうまく行かず、色々と試行錯誤結果「前段で文字列として加工してしまおう」ということになりました。 そのため追加したノードが次の template ノードです。

templateノード(③)

ここでやっていることは単純で msg.payload の内容を加工して msg.payload に詰めなおす、というものです。 今回は前段のmsg.payload(=アクセストークン)に対し、 Bearer という文字列を付与して msg.payload に渡すといったことをやっています。 これよりいい方法がありそうですが、今回はこちらで進めようと思います。

補足

Node-REDではMustache記法が利用可能です。 これを使うことで、変数を文字列中で展開することができます。

debugノード(④)

今回はhttp requestノードの実行結果をそのまま見ようと思い、対象を msgオブジェクト全体にしています。 これで準備ができたので実行してみます。

実行結果

フローを実行すると上記のように表示されました。 今回は idが実質的に1固定でしたが、渡し方を工夫することでより柔軟に使うことができそうです。

おわりに

今回はコマンドやプログラムを使わず、Node-REDで用意されたものを使ってグラフィカルにSynergy!データベースAPIの実行フローを作ってみました。

もちろん、このNode-REDを動かすための環境や、今回は省略したAPIの定義登録など、どうしても技術的なアプローチは必要になります。 さらには業務目的で使うのであれば、上記のような単純なフローではなく、もっと複雑で、エラー処理などもきちんと作る必要があります。

ただ、それでも全てをコマンドやプログラムで制御するより、はるかに簡単で直観的にできます。 どうしてもAPIというと難しいという印象を与えがちですが、こういったツールを使うことでもっと身近になれたらいいなと思っています。

シナジーマーケティング株式会社では一緒に働く仲間を募集しています。