まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

LINE Developers から提供されている LIFF(LIne Frontend Framework) は LINE のフロントエンドアプリケーションを開発するためのフレームワークです。このブログでも何度か触れる機会がありました:
http://dotnsf.blog.jp/tag/liff


これまで LIFF は LINE Developers 内の Messaging API チャネルの一部として提供されていましたが、先日のアップデートで Messaging API チャネルからは追加できなくなり今後は LINE Login チャネルの一部として提供されるようになりました:
2020031103

2020031102


さっそく自分がこれまでに作ってきた LIFF アプリも LINE Login チャネルでも動くことを動作確認・・・したのですが、うまく動いてくれないのでした。その記録の意味も兼ねてこのブログエントリを書いています。

(追記 2020/03/14)
解決しました。詳しくは後述。
(追記終わり)


まず LIFF の SDK のバージョンは 2.1 です。これは Messaging API チャネルの頃と同じもの(URL も同じ)です。したがって基本的にアプリケーションソースコードは Messagin API チャネルのものから変更する必要はない(後述の LIFF ID の変更のみ必要)と理解しています。

LINE Login チャネルの中で LIFF アプリを定義する方法や設定内容で動作に違いがでる可能性はあると思っていますが、今回用意した LINE Login チャネル上の LIFF アプリはスコープなど可能な限り緩めの設定にしており、この設定内容が後述のエラーにつながっているとは考えにくいと思っています:
2020031101


作業としては基本的には LIFF SDK v2.1 の作法に従っているだけですが、一応説明します。Messaging API チャネルで作った時と同様に、まずは LIFF アプリ(ウェブアプリ)のエンドポイント URL を指定して LIFF アプリを LINE Login チャネル内に定義します。この時点で LIFF URL が生成され、LIFF ID(LIFF URL の line://app/XXXXXXXXXX の XXXXXXXXXX 部分。下図だと "16" で始まる文字列)が取得できます:
2020031104


次にエンドポイント URL の先で動くウェブアプリケーションを用意します。まず LIFF SDK v2.1 をロードする必要があるため、以下の行をページ内に追加します:
<script src="https://static.line-scdn.net/liff/edge/2.1/sdk.js"></script>

画面ロード時の JavaScript で LIFF を初期化します。この時のパラメーターとして上記で取得した LIFF ID (XXXXXXXXXX 部分)を指定します:
$(function(){
  liff.init( { liffId: 'XXXXXXXXXX' } ).then( function(){
    :
    :
  }).catch( function( err ){
alert( JSON.stringify( err ) ); }); : : });

※ここまでは成功していること(init() 時に catch() 内が実行されていないこと)を確認しています。


初期化が成功していれば LIFF の各種関数が使えるようになります。このアプリでは HTML5 の Canvas を使って指でお絵描きをして、「送信」するとその画像を元のトークルームにスタンプのように送信するという処理を実行しています。もう少し詳しく説明すると、「送信」すると Canvas 内の絵をまず PNG 画像に変換してサーバーにアップロードします。アップロードまでが成功したらその画像を表示するための URL (img_url)を指定して以下のコードを実行しています:
var data = {
  type: "image",
  originalContentUrl: img_url,
  previewImageUrl: img_url
};

liff.sendMessages( [ data] ).then( function(){
  //. トークルームへの送信成功
  alert( '送信されました' );
  liff.closeWindow();
}).catch( function( err ){
  //. トークルームへの送信に失敗
  alert( JSON.stringify( err ) );  //. エラーメッセージを表示
});

指で描いた絵をトークルームに送信する処理が成功すると「送信されました」というメッセージが表示され、LIFF アプリのウィンドウが閉じられます。送信処理に失敗すると LIFF のサーバーから返ってきたエラーオブジェクト(err)を文字列化して表示する、という処理を実行しています。


繰り返しますが、この内容は Messaging API チャネル内に作った LIFF アプリでは成功していました&今でも成功しています。

(Messaging API チャネルでの挙動 LIFF URL をタップしてアプリを起動)
2020031201


(Messaging API チャネルでの挙動 ペンの色や太さを変えながら指でお絵描き)
2020031202


(Messaging API チャネルでの挙動 送信するとトークルームに表示される)
2020031203



しかし同じアプリを LINE Login チャネルに作った LIFF アプリで実行すると、liff.init() は成功するのですが、liff.sendMessages() に失敗します。失敗時に返される err オブジェクトを表示すると以下のようになりました:
2020031203


直接の原因がどこにあるのかはわかりませんが、メッセージでは LIFF SDK の JavaScript 内でエラーが発生していたようで、これ以上の原因調査が難しい状況です(少なくとも今のこの時点では SDK 側に問題があって、誰が実行しても同じ結果になるような気がしています・・・)。


なおここで紹介している LIFF アプリ自体はもともとオープンソースとして公開していました。IBM Cloud を使う前提で作られていますが、無料プランの枠内で使えるものです。現在はこの問題のために動かない(登録済みの Messaging API チャネルの LIFF アプリとすれば動く)状態のものですが、詳細なソースコードはこちらから参照いただくことも可能です:
https://github.com/dotnsf/line_liff_doodle

(↑現在はこの問題を調査するためのデバッグ用コードも多少含まれているので、少し見にくい部分もあると思います。ご了承ください)


(追記 2020/03/13)
全く同じソースコードを Messaging API チャネルで取得した liff_id と、LINE Login チャネルで取得した liff_id だけを変えて、同じサーバーにデプロイして動作確認の比較(ようするに liff.init 実行時のパラメータだけを変えて実験。2つの LIFF アプリのエンドポイント URL は同じ)。

結果: Messaging API チャネルの LIFF アプリではイラスト送信に成功、LINE Login チャネルの LIFF アプリは上述のエラー。

やはり LINE Login チャネルの LIFF アプリでは sendMessages が動作しない可能性が高いと判断。
(追記おわり)



この問題、LINE developers community にも報告済みですが、まだ解決していません。上述しましたが、今から作る LIFF アプリは Messaging API チャネルではなく LINE Login チャネルを使う必要があるため、既に Messaging API チャネルで動いている LIFF アプリはともかく、これから作る LIFF アプリでは動かないように思えます。この LINE お絵描きスタンプは IT 勉強会とかでも人気の開発ネタなので、できれば今でも動くようになって、再び勉強会とかで使えるようになってほしいと思っています。


(追記 2020/03/14)
この問題は LINE developer community で返答があり解決しました。原因としてはアプリの Scopes 設定が足りなかったというものでした。下図の View all ▼と書かれた箇所をクリックすると・・・
2020031401


更に選択肢が出てきました。この中の "chat_message.write" を選択して保存すると、sendMessages を実行する権限が与えられて動くようになるようでした:
2020031402


(愚痴ですが)"View all ▼" って書かれたいたら(既に展開済みで)ここが展開できるように見えない・・・


(追記おわり)

 

Node.js で XML を扱うのは難しいので、いったん JSON に変換してから扱うことが多いと思っています。そんな場合に自分はよく xml2json というライブラリを使っていました。

xml2json はその名前の通り、XML を JSON に変換してくれるパーサーを実装したライブラリです。使い方は例えば以下のような感じで、XML 文字列をそのまま引数にして実行すると、結果が JSON 文字列となって戻してくれます(JSON の文字列ではなく JSON オブジェクトとして扱う場合は更に JSON.parse() を実行します)。挙動も速く、便利に使っていました:
  :
var parser = require( 'xml2json' );
  :

  :
var xmlStr = fs.readFileSync( xml_filename, 'utf-8' );   //. ファイル名を指定して XML 文字列を取得
var jsonStr = parser.toJson( xmlStr );                   //. XML 文字列を JSON 文字列に変換
var jsonObj = JSON.parse( jsonStr );                     //. JSON 文字列を JSON オブジェクトに変換
  :

ところが上述のような処理を記述した Node.js のソースコードを Windows 環境下で実行しようとした時に問題が発生しました。実行前のライブラリインストール(npm install)の段階でエラーが発生してしまうのでした。詳細なエラーメッセージ等は後述のリンク先を参照していただきたいのですが、node-expat という xml2json の依存ライブラリを node-gyp でビルドする際に何やらエラーが発生していました。

で、この現象を調べた所、どうやら Windows 環境下では xml2json ライブラリ自体がビルドできないという根本的な問題を抱えているようでした:
npm install xml2json error


※厳密には「ビルドできない」わけではないけど、別途 Python や Visual Studio C++ 2012 などの他にインストールする必要があるツールが多く存在しているようです。


↑リンク先でも回避策として「別の XML -> JSON 変換ライブラリを使う」ことが提案されています。というわけで Windows でも使える同機能のライブラリを探したところ、単純な変換であれば fast-xml-parser が使えそうでした。

fast-xml-parser を使う場合は、上述の内容は以下のようなコードになります:
  :
var parser = require( 'fast-xml-parser' );
  :

  :
var xmlStr = fs.readFileSync( xml_filename, 'utf-8' );   //. ファイル名を指定して XML 文字列を取得
var jsonObj = parser.parse( xmlStr );                    //. XML 文字列を JSON オブジェクトに変換
  :

現実問題として自分個人の開発環境として Windows がベースとなることは今のところ考えにくいのですが、(WSL とかではなく)Windows 環境下で開発しないといけない人との共同作業が発生するようなケースではこういったことも意識しないといけないこともでてくると感じています。


社内ネットワークに Proxy サーバーが設置されている環境は珍しくないと思いますが、そのような環境下でパブリッククラウドを利用して開発作業を行ったり、アプリケーションをデプロイする際に Proxy 環境に応じた設定が必要になります(ついでにいうと、そのような環境下では特定ポート以外を通さない設定になっていることも多いので、単なる Proxy 対応だけでは不十分なこともあります)。

実際にそのような環境でのお客様対応を通じて苦労した得た情報を設定手順含めて共有します。なお以下は IBM Cloud を使ったケースとして紹介していますが、そこそこ広くパブリッククラウド利用時に役立つ情報だと思っています。


【Proxy 環境下で git コマンドを使う】
コマンドプロンプトやターミナルを開いて以下を入力します:
$ git config --global http.proxy http://my.proxyserver.com:8080

$ git config --global https.proxy http://my.proxyserver.com:8080


なお http://my.proxyserver.com:8080 部分は Proxy サーバー名およびポート番号です(以下も同様)。


【ssh でなく https で github(gitlab) を使う】
これは Proxy とは直接関係ないのですが、ssh プロトコル通信が閉じられているような環境下でプライベートな github(gitlab) リポジトリを使いたい場合の、つまり https プロトコルでプライベートな github(gitlab) リポジトリを使う場合に必要な設定項目です。 作業内容としては Private Access Token を設定することで https でも認証が可能になり、プライベートリポジトリを利用することができるようになります。以下 github を使う前提での画面で紹介しますが、gitlab でもほぼ同様です。

まず github にログインし、画面右上の "Settings"  を選択します:
2020022801


次に画面左の "Developer Settings" を選択します:
2020022802


Developer Settings のメニューから "Personal access tokens" を選択し、画面右の "Generate new token" ボタンをクリックします:
2020022803


新たに生成するトークンの設定を指定します。まず名前を(myToken など)適当に入力し、scopes を選択します(わからなければとりあえずは全部):
2020022804


そして最後に画面下部にある "Generate token" ボタンをクリック:
2020022805


すると以下のような画面になり、トークン文字列が表示されます。この文字列はこの一回しか表示されません(一度異なるページを表示した後に再度表示する方法は用意されていません)。別ファイルにコピーするなどしてこの値を再度入力できるようにしてください:
2020022806

ここまで完了していれば、以下のコマンドで https プロトコルだけで github から git clone ができます:
$ git clone https://github.com/aabbcc/xxyyzz.git
 Username: (GitHub のユーザー名)
 Password: (取得したトークン文字列)

なお gitlab の場合は以下のようになります:
$ git clone https://gitlab.com/aabbcc/xxyyzz.git
 Username: oauth2
 Password: (取得したトークン文字列)

【Proxy 環境下で npm コマンドを使う】
サーバーサイド JavaScript である Node.js を使ってアプリケーションを開発する場合、ほぼ npm コマンドを併用することになると思っています。この npm コマンドを Proxy 環境下で使う場合にも設定が必要です。
$ npm -g config set proxy "http://my.proxyserver.com:8080/"
$ npm -g config set https-proxy "http://my.proxyserver.com:8080/"
$ npm -g config set registry "http://registry.npmjs.org/"

proxy と https-proxy の設定をすれば動くはず、ですが、この2つだけではエラーになることがあるらしいです。その場合は registry も設定してください。


【Proxy 環境下で cf コマンドを使う】
これは IBM Cloud 環境に特化した設定かもしれませんが、PaaS である Cloud Foundry ランタイムにアプリケーションを push(デプロイ)する際に利用する cf コマンド(ibmcloud cf コマンド)も Proxy 環境下ではそのための環境設定をしないと使うことはできません。

※Delivery Pipeline サービスを利用することで、cf コマンドを使わずに Git と連動してデプロイすることは可能です。


具体的には環境変数の設定を行う必要があります。以下は Windows 10 での環境変数設定方法です。

コントロールパネル - システムとセキュリティ - システム - システムの詳細設定 を選択します:
2020022807


「詳細設定」タブの「環境変数」ボタンをクリック:
2020022808


ユーザー環境変数で「新規」ボタンをクリック:
2020022809


新しいユーザー変数として、以下の2つを設定します:
変数名変数値
http_proxyProxy サーバー URL
https_proxyProxy サーバー URL

20200228010


2つの環境変数が新たに追加されていることを確認します:

20200228011


これで cf コマンドを指定した Proxy サーバー経由で実行することができるようになりました。

このページのトップヘ