IBM Cloud FunctionsでNode.jsのパッケージを利用してみた


はじめに

この記事は、LINEとIBM Cloud Functionsを連携したSlackへの通知機能を作ったので、3回に分けて紹介したい記事の第2回になります。
 第1回:IBM Cloud Functons 動かしてみた
 第2回:IBM Cloud FunctionsでNode.jsのパッケージを利用してみた ← この記事
 第3回:IBM Cloud Functions でLINEとSlack連携させてみた
今回は、アクションにNode.jsのパッケージを利用して、より自由な処理を作れることを紹介したいと思います。

用意するもの

注意

今回ご提示する方法は、ローカルPCでデバッグできるようなやり方ではなく、都度IBM Cloud Functionsにアクションを登録(更新)して動作を確認するものになります。

注意2

普通の反応「せっかくブラウザ上でコード編集できるのに、ローカルPCでコード書かないとあかんの?」
IBM Cloud「せやねん。すまんな。。。」

例えば、Functionsで利用可能なNode.jsのパッケージをリンク先で公開されていますが、ブラウザで編集可能なアクションのコードにパッケージを記述しても利用できなくて、ローカルPCで作成したコードと、利用したいパッケージを宣言した package.json をFunctionsにアクションとして登録する必要があります。

コーディング

さて、紹介なので、簡易なコードにしましょう

package.json

request パッケージを利用したいので、dependencies に登録しています

package.json
{
  "name": "qiita-action",
  "version": "1.0.0",
  "main": "action.js",
  "dependencies": {
    "request": "^2.88.0"
  }
}

action.js

どんな紹介コードが良いかと考えましたが、前回に公開したAPIにアクセスするようにしましょう。

action.js
// 実行するメソッド
const main = async ( params ) => {
  // 前回に公開したAPIを設定、params に name があれば、それを設定しています
  const apiUrl = 'https://81fe65f5.jp-tok.apigw.appdomain.cloud/function-api/helloworld';
  const callUrl = params.name ? `${apiUrl}?name=${params.name}` : apiUrl;
  // HTTPリクエストのオプションを指定します
  const getHttpRequestOption = {
    method : "GET",
    url : callUrl,
    headers : {
      "Content-Type": "application/json",
    }
  }
  const response = await callAPI(getHttpRequestOption);
  const bodyJson = JSON.parse(response.body); // bodyのJSONがescapeされているので、JSONに戻します
  return bodyJson;
}

// requestのパッケージを利用する処理を外出ししています
const callAPI = (httpOption) => {
  return new Promise((resolve,reject) => {
    const request = require( 'request' );
    request( httpOption, ( err, res, buf ) => {
      if( err ){
        reject( { status: false, error: err } );
      }else{
        resolve(res);
      }
    });
  })
}
// IBM Cloud Functions では、 `main` メソッドが外部から呼び出されるので、exportsが必須です
exports.main = main;

アクションの登録

IBM Cloudへのログインと環境の確認

とりあえず、CLIでIBM Cloudにログインしましょう。今回は東京リージョン( jp-tok )を選択しています。

コマンドプロンプト
# ログイン
ibmcloud login -u [登録アドレス] -p [登録パスワード]
# リージョンの指定
ibmcloud target -r jp-tok
# Functionsのプラグインが導入されているか確認
ibmcloud plugin list | findstr function
  cloud-functions/wsk/functions/fn       1.0.44

コードをZIPに固める

今回作成した package.jsonaction.js をZIPファイルにする必要があります。
作業ディレクトリに両ファイルがある前提で、以下のコマンドでZIPファイルを作成します。qiita-action.zipが出力されるはずです。

Windows
powershell Compress-Archive -Path action.js,package.json -DestinationPath qiita-action.zip -Force
Mac/Linux
zip -r qiita-action.zip action.js package.json

アクションをCLIで登録

初回(新規登録)と2回目以降(更新)でコマンドの指定が変わるので注意してください。正常に登録できると ok が表示されます。

# 初回アクション作成時
ibmcloud fn action create qiita-action qiita-action.zip --kind nodejs:10
  ok: created action qiita-action

# 2回目以降(更新時)
ibmcloud fn action update qiita-action qiita-action.zip --kind nodejs:10
  ok: updated action qiita-action

ブラウザで確認

無事に、アクションが登録されていますね。今回はアクションを何かしらのFunctionsのパッケージに紐づけているわけではないので、デフォルト・パッケージ の部分に追加されているはずです。

起動してみよう

起動 をクリックすると、しばらく時間がかかってアクティベーションの欄に、前回のAPIを呼び出した結果が取得できていることがわかります。
吹き出しに記載しましたが、ZIPでアクションを登録すると、コード自体をブラウザで編集することはできなくなってしまいます。

パラメータも指定してみよう

前回操作したように、パラメータを付けて起動をクリックして、nameのパラメータを指定してみます。

起動してみると、無事にパラメータを前回公開したAPIに渡せているようです。

作成したアクションをAPIで公開

基本的に操作は、前回と同じです。
Functionsのトップページから API を画面左部から選択して、前回作成したAPIが表示されるので、そちらをクリックします。

次に、画面左部の定義および保護を選択し、操作の作成を選択して、新しいAPIを作成します。

今回のAPIはPOSTでリクエストを受取るようにしてみましょう。
アクションを含むパッケージでは、今回アクションが登録されているデフォルトを選択し、アクションの部分で、今回登録したアクションを選択していることを確認しましょう。

操作を作成したら、元の画面下部で保存を忘れずにクリックして更新してください。

公開されたAPIの確認

ブラウザで、今回登録したAPIを呼び出してみましょう。

今回はPOSTでリクエストを処理する設定にしているので、ブラウザにURLを貼り付けるだけのGETでは処理されないことが確認できました。想定通りですね。

では、VSCodeの拡張機能REST Clientを利用して POST で呼び出してみましょう。
無事にレスポンスで、前回公開したAPIの応答結果を受取れていることがわかります。

さいごに

いかがでしたでしょうか?Node.jsのrequestのパッケージを利用して、呼び出されたAPIが別のAPIを呼び出して、その結果を応答するということが出来ました。
つまり、IBM Cloudに関わらず、世の中のAPIを利用したIBM Cloud Functionsのアクションを作成する準備が完了したということです。
次回は、今回のコードをベースに、LINESlackのAPIを利用して、LINEに投稿された内容をSlackに通知する機能の実装について紹介したいと思います。
 第1回:IBM Cloud Functons 動かしてみた
 第2回:IBM Cloud FunctionsでNode.jsのパッケージを利用してみた
 第3回:IBM Cloud Functions でLINEとSlack連携させてみた