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

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

LINE のフロントエンドをカスタマイズするフレームワーク LIFF(LIne Front-end Framework) の新機能 targetSharePicker を使ってみました。


まずこれまでも LIFF を使ったアプリは公開しているもの/していないもの合わせて多く作ってきました。LIFF SDK のバージョンが v2.1 になってからの変更に振り回されつつ、魅力的な新機能を試してきました。今回紹介する targetSharePicker も最近実装された新機能の1つです。どんな機能なのかを試せるサンプルアプリを期間限定で公開しているので、興味ある方は後述の URL にアクセスして使ってみてください。

アプリのベースにしているのはオープンソースとして公開している「お絵描きスタンプ」です:
72c4d934-s


LINE のトークルーム内に LIFF URL と呼ばれる特殊な URL を貼り付けてからタップすると、指でお絵描きできるキャンバスが現れ、最後に POST すると描いた絵がスタンプのように元のトークルームに表示される、というものです。以前にこのブログでも紹介しているので興味ある方はこちらもご覧ください:
お絵かき LIFF アプリを作ってみた


この LIFF アプリは(LIFF SDK v1.0 の頃に作ったものですが)HTML5 の Canvas を使って絵を描き、IBM Cloud に絵の画像を保存してから(画像を URL で表示できるようにしてから)、LIFF SDK の関数である sendMessages() を使って画像の URL をトークルームに送信することで実現しています。IBM Cloud の勉強会などでもネタとして使っていて、人気コンテンツの1つです。

今回 shareTargetPicker に対応した LIFF アプリケーションもベースはこのままです。LIFF URL を取得して、トークルームに貼り付けた URL をタップして起動させた場合は全く同じように使うことができます:
2020031403


ただ今回の対応で少し進化している部分もあります。それは(上記画像内にも表示されていますが)実際に動いているウェブアプリケーションの URL(上記では https://line-liff-doodle-2020.mybluemix.net/ )に PC のウェブブラウザからも利用できるようにしている点です。実際にウェブブラウザ(FireFox または Chrome )でこの URL を開くと、初回は LINE へのログインを求められるので、ID とパスワードを入力するか QR コードを利用して自分の LINE アカウントでログインしてください:
2020031405


LINE にログイン後、ウェブブラウザでアプリケーションの画面が表示されます。当たり前ですがスマホの LINE で開いた時よりも大きなキャンバスが表示されます。ここにマウスで絵を描いてもいいですし、タッチスクリーン対応の PC であれば画面に直接指で描くこともできます。またペンタブレットを持っている方であればペンタブで描くこともできます:
2020031406


こんな感じで描き終わったら、スマホの時と同様に POST ボタンをクリック。すると・・・
2020031401


別ウィンドウが開いて友達の一覧が表示されます。ここから描いた画像を送信したい人を選んで「シェア」すると・・・
2020031402


選んだ人に PC ブラウザで描いた画像がスタンプのように送信されます。これが今回作った新機能です:
2020031404


実現方法としては(PC から送信する場合は)LIFF の sendMessages 関数ではなく、shareTargetPicker 関数を使っています(実行パラメータの指定方法や内容は sendMessages と同様です)。またこの機能を実現するために(PC から実行しているのか、LINE アプリから実行しているのかを判断するために)isInClient 関数なども併用しています。興味ある方は公開しているソースコードを参照ください:
https://github.com/dotnsf/line_liff_doodle

(↑ソースコードの中で LIFF や targetSharePicker を使っている該当ファイルは public/index.ejs 内です)


この新機能の最大のメリットは、これまでどうしても LIFF URL の共有方法が(最初に入力する必要があったり、友達登録した上で送信したりする必要があったため)面倒だったのですが、新しい方法であれば LIFF URL を意識する必要がなくなったことです。単にウェブブラウザから URL を指定して開き、(ログインし、)絵を描いて POST する際に友達一覧から送信先を選ぶことができるようになったので、アプリケーションの URL だけを(必要であれば QR コードや短縮 URL などにした上で)事前に教えておけばよくなりました。またこれまでの LIFF URL を使う方法だとトークルームごとに LIFF URL を貼り付けておく必要がありましたが、新しい方法であれば送信時に宛先(トークルーム)を指定できるので、トークルームごとに用意しておく必要がなくなる、という副産物的なメリットも生まれます。

※理想を言うとスマホのウェブブラウザからも shareTargetPicker が使えるといいですが、スマホのブラウザはセキュリティ設定が厳しくて友達一覧のポップアップをできるようにするまでの設定がちと面倒です。詳しくはこちら:
http://dotnsf.blog.jp/archives/1077186965.html


というわけで、予定としては3月いっぱいまで以下の URL を公開するので、PC から LINE へのお絵描きスタンプを試したい場合は使ってみてください:
https://line-liff-doodle-2020.mybluemix.net/


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 環境下で開発しないといけない人との共同作業が発生するようなケースではこういったことも意識しないといけないこともでてくると感じています。


このページのトップヘ