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

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

2020年03月

タイミングいいのか悪いのかわかりませんが、新型コロナウィルスの影響でしばらくしばらく千葉県に引きこもることになりそう・・・って所から今回のブログネタを思いつきました。

オープンソースで公開された東京都の新型コロナウィルス感染症対策サイトが話題になりました:
https://stopcovid19.metro.tokyo.lg.jp/

2020032601


オープンソースで公開されていることに加え、扱うデータもオープンデータを活用していることで他の自治体へも活用される動きが広がっています。スピード感も含めオープンソースやオープンデータはこういう時に強いですよね。


そんな流れに触発されたこともないわけではないのですが、自分もオープンデータを使ったサービスを作れないだろうか、それもできれば比較的得意としている地図情報を使う形で、、、といった経緯の中で1つアイデアを思いついて簡単な実装までしてみました。

技術的な説明は後述しますが、まずは動いているサービスをご覧ください。 PC またはスマホのブラウザで以下のサイトにアクセスしてください:
https://dotnsf.github.io/geojsonjapan/

2020032501


上記のような東京を中心とした日本地図が画面いっぱいに表示されます。画面左上の+ーで拡大縮小したり、マウスのドラッグ(スマホの場合はピンチイン/アウトやスクロール)で表示位置を変更することができます。

その上で、日本地図の陸地部分のどこかをタップすると、そのタップされた地点がどの都道府県に属しているのかがポップアップで表示される、というものです(下図は東京都の皇居付近をタップした時の様子):
2020032502


サービスとしてはただこれだけなんですが、そこそこの精度を実現しています。例えば千葉県の、チーバ君でいえば鼻の先端部分のこのあたり、、、
2020032503


千葉県民であれば常識だと思いますが、千葉県は四方を太平洋、東京湾、利根川、そして江戸川に囲まれていて、川にかかる橋を除けば全ての県境が水の上、と思われています。実際ほぼその通りなんですが、上記部分を拡大してみるとこんな感じになっています:
2020032504


向かって右側が利根川、左側が江戸川で、この2つに挟まれた三角州部分。そのわずかな先端部分だけはなぜか千葉県ではなく茨城県になっているのでした。そういった細かな県境がこのサービスではどうなっているかというと・・・ ちゃんと対応しています:
2020032505


また千葉県に関して言えば、富津岬の先にある2つの海堡も含めて対応しています。千葉県に限らず、そこそこ細かな所までは対応した都道府県判定ができていると思っているサービスです:
2020032506


もともとは「ジオロケーションを使って利用者の位置情報を取得して、香川県からのアクセスだとわかったら・・・ (^^; 」などと考えながらはじめた取り組みだったりしたのですが、対応範囲を日本の全都道府県にして、更に地図情報を連携させた結果がこういう形になりました。これ自体が何らかの直接の役に立つものではないと考えていますが、後述する技術要素も含めて今後更に精度を高めるためのカスタマイズをしたり、今後は「地形から場所を推測する」なんてことにも挑戦したいと考えていたりします。


以下、このサービスを実現するにあたっての技術要素の紹介です。興味ある方は引き続きご覧ください。

まずこのウェブサービスアプリケーションはオープンソースとして公開しています。興味ある方はこちらもどうぞ(実質的には index.html だけで実現しています):
https://github.com/dotnsf/geojsonjapan


次にこのサービスの URL (https://dotnsf.github.io/geojsonjapan/)を再確認いただきたいです。わかる人はわかると思うのですが、Github Pages を使って公開しているサービスです。要は Github のリポジトリを使い、静的なファイル(index.html)をウェブサーバーで表示することで、このサービスは成立しています。つまり外部 API 連携を含めたバックエンド機能を一切使わずに実現しています。では改めてその制約条件の上でどのような仕組みやロジックでこのサービスを実現しているか、わかりますか?


このサービスを実現する上で、以下のような実装をしています:
  1. 地図情報に OpenStreetMap 、地図操作ライブラリに Leaflet.js を使って、ブラウザ上に日本地図を表示する
  2. 各都道府県ごとの geoJSON ファイルを使って、日本地図上に各都道府県ごとの透明なレイヤーを重ねる。その際にレイヤーがタップされた場合に都道府県名がポップアップされるようなハンドラを定義する
  3. 各都道府県ごとの geoJSON ファイルはオープンデータとして提供されているものから作ったファイル(japan.geojson)を利用する。index.html からこの geoJSON ファイルを AJAX で取得して利用する

つまりオープンソースのツールと、オープンデータだけで作ったサービスということになります。

geoJSON ファイルについては補足しておきます。geoJSON とはこの地球上における緯度・経度、およびこれらの配列を用いて点、線、多角形、多角形の組み合わせを JSON ベースで表現する標準フォーマットです。上述の Leaflet.js も geoJSON に対応しており、関数一発で geoJSON のレイヤを地図上に追加することができたり、そのレイヤに対するクリックイベントハンドリングなどが実現できます。

今回公開したこのサービスでは、上述のように国土地理院から提供されている地球地図日本のデータを geoJSON ファイル化したものを使っています。このファイル(japan.geojson)を index.html からAJAX を使って読み込み、各都道府県の feature データごとに Leaflet.js の geoJSON メソッドでレイヤに追加しています(同時に bindPopup メソッドでレイヤがタップされた時の処理も定義しています)。オープンソースとオープンデータだけでここまで作れちゃうんですねー。

なお都道府県レベルではなく市区町村レベルで同様のことができるかというと、国土交通省の行政区域データを使って作られたものは存在しているので、仕組み上はそのままでもできないことはないと思います。一方で市区町村レベルとなるとデータ量がかなり膨大となってしまうため、そのままデータだけ変えて実現してしまうと通信料(量だけでなく料)の問題が発生しかねないと思っています。

一方このデータの精密度について、充分であるとは思いますが、まだまだ厳密性に欠ける部分もあります。例えばいわゆる「飛び地」データは僕が知る限りで試した範囲では存在していませんでした(つまり未対応)。例えば有名な所では埼玉県に囲まれた東京都練馬区西大泉町はこのデータでは「埼玉県」扱いになっています:
2020032602


また実際の geoJSON データを地図上に重ねてマッピングしてみると、そこまで正確とは言えない内容でした(※そもそも地図データ側がどこまで正確か、という問題もあるとは思っています):
2020032507

↑上述の富津岬部分の geoJSON データ、結構荒い・・・


ただ大事なことは API のようなブラックボックスではなく、ここまでの基礎情報がオープンデータとして提供されており、オープンソースのツールや標準化によってここまで実現でき、必要であれば自分で手元のデータを改良(カスタマイズ)して使うこともできるような形で実現できている、という点です(geoJSON は飛び地のようなデータにも対応したフォーマットです)。オープンデータとフロントエンド機能だけでここまで実現できるようになっていることには、あらためて位置情報サービスの人気や広がりを意識するし、今後のさらなる広がりにも期待できます。

以前にも似たようなものを何度か作ったことがあったのですが、その最新改良作品です。 ツイッターでのつぶやき内容を元に自分の性格を分析して、その内容が時間とともにどのように変化していくか、を視覚化するというものです。

実際に自分の3月21日時点でのツイートを元にためしてみた結果がこちらです。なお現時点でスマホで表示する場合はレイアイトが最適化されていないため画面を横にして御覧ください:
https://personality-transition.mybluemix.net/transition/6f24cd50fa6f528cdd3162aadb716b03

2020032101


画面は最上部にシェア用のアイコンが並んだ下に性格を分析した本人の twitter アイコンと名前が表示され、その下に IBM Watson Personality Insights API を使った分析結果の「性格分析」と「消費行動動向」が表示されます(「消費行動動向は初期状態では省略表示されているので、内容を表示するには三角形部分をクリック(タップ)してください)。

性格分析はビッグ5と呼ばれる5つの性格要素(知的好奇心、誠実性、外向性、協調性、感情起伏)に加え、ニーズ(共感を呼ぶ度合い)&価値(意思決定に影響を及ぼす要素)という7つのカテゴリを更に細分化した結果がレーダーチャートで表示されます:
2020032102


また消費行動動向はその性格から結びつく消費行動の度合いが表示されます(色の濃い方がその要素が高く、薄い方が低い、という意味です):
2020032103


画面最下部にはスライダーが表示されています。初期状態では一番右にセットされていて、これは時間的に一番新しい分析結果が表示されていることを意味します:
2020032104


このスライダーを左に移動していくと少しずつ前の(古い)性格分析結果や消費行動動向が表示されていきます。自分の性格が時間とともにどのように変化していったのか/変わらない要素は何か といった内容がわかるようになる、というものです:
2020032105


このページの画面右上のリンクから皆さんのツイートでも試すことができます。興味ある方はぜひ挑戦してみて、よろしければその結果を SNS でシェアしてみてください:
https://personality-transition.mybluemix.net/transition/6f24cd50fa6f528cdd3162aadb716b03



以下、このサービスを実現する上での技術要素の説明です。なおソースコードは公開していますので興味ある方はこちらも参照ください。なお IBM Cloud を使って動かす想定のコードとなっており、後述の IBM Watson やデータベース機能含めて無料のライトアカウントの範囲内でもデプロイ可能な内容となっています:
https://github.com/dotnsf/personality_transition


このサービスは Node.js で実装していますが、サービスを実現する上で利用しているライブラリは大きく3つです。1つ目は Twitter のログイン認可を実現するための OAuth 、2つ目は認可したユーザーのツイートを取得するための Twitter API 、そして3つ目は取得したツイート内容から性格分析を行う IBM Watson Personality Insights API です。

なお、ここで使っている IBM Watson Personality Insights は IBM Cloud から提供されている IBM Watson API の1つで、テキストの内容を使用単語レベルで分析し、そのテキストを記述した人の性格や、その性格毎の購買傾向を取得する、という便利な API です。日本語を含む5ヶ国語に対応しています。詳しくはこちらも参照ください:
https://www.ibm.com/watson/jp-ja/developercloud/personality-insights.html


おおまかな処理の流れとしては、まず OAuth2 で Twitter にログインしてもらうことで、そのユーザーの権限で Twitter が操作できるよう認可します。そして Twitter API でユーザーのタイムライン内容を取得します。 この時に直近の 200 ツイートを取得します。この 200 件のツイートを投稿時刻の順に 40 件ずつ5つのブロックにわけます。そして各ブロック毎のツイート内容をそれぞれまとめて IBM Watson Personality Insights API を使って性格分析を行います(つまり1回の処理で Twitter のタイムライン取得 API を1回、IBM Watson Personality Insights API を5回実行します)。このようにすることでツイートの内容を時間で区切って直近のものから少しずつ時間を遡りながら5回ぶんの性格分析を行い、その結果を上述のようにスライダーバーで時間ごとに表示/非表示を切り替えることで実現しています。

機能的にはこれだけでもできるのですが、このサービスでは「分析結果をシェア」できるようにしました。シェアするためには(シェアされた人はツイートを取得せずに分析結果を見ることができる必要があるため)分析した結果をデータベースに格納する必要があるため、データベースも併用しています(あくまで分析結果を保存するためのもので、ツイート内容は保存していません)。

また上述のような仕様であるため、仮に Twitter 上で非公開アカウントとしているアカウントに対しても(本人の権限でツイートを取得することになるので)性格分析を行ったり、その結果をシェアすることができます(公開許可されていない人や、そもそも Twitter アカウントを持っていない人でも分析結果を見ることができます)。ただしあくまで分析結果だけがシェアされるのであって、ツイート内容がシェアされるわけではない点はご安心を。


このデモサービスでは Twitter のツイートを元に性格分析を行っていますが、必ずしも分析元はツイートである必要はありません。1人の人が書いた文章であればよいので、メールなり、社内掲示板なりからテキストを取得することができるのであれば理論上は可能です。ただし1回の性格分析におけるテキストの単語数が少ないと充分な精度がでない結果となることも考えられます。ある程度の単語数が含まれるテキストを取得できる必要があります(このサービスでは上述のように 40 ツイートぶんのテキスト内容をひとまとめにして分析しています)。

また IBM Watson Personality Insights API の特徴でもあるのですが、単にテキスト内容とその単語傾向から性格を分析するだけでなく、購買行動への傾向と合わせた実行結果を得ることができます。つまりまだ何も買っていないユーザーに対してでも、その購買傾向を調べた上でレコメンドを出したり、特定興味分野の広告を出したりする、といった使い方にも応用ができるもので、特に今回のデモではその時間変化にも着目できるようにしています。応用の幅が非常に大きな API であると考えていて、その一部が伝わればいいと思っています。

 

ブラウザ内で動作するウェブアプリケーションの中で「別ウィンドウで画面を開く」という操作をしたい場合に大きく以下の2つの方法があります:
(1)target="_blank" 属性のついた <a> タグをクリック/タップする
(2)JavaScript の window.open 関数を実行する


より一般的な方法は(1)だと思っています。リンク時に使う <a> タグに target="_blank" という属性を含めておくことで常に新しいブラウザウィンドウを(ブラウザによっては別タブを)開いて、その新ウィンドウの中でリンク先ページが表示されるというものです。比較的簡単に実装できる方法です。

※ <a> タグの target 属性は本来は「ウィンドウを指定して開く」機能です。例えば <a target="abc" ..> というタグをクリックすると abc という名前のウィンドウを探して(存在していない場合は新ウィンドウを作って abc という名前で管理して) abc ウィンドウの中で目的先のリンクを開きます。再度同じ <a> タグをクリックすると、(ユーザーが消していない限り)既に abc ウィンドウは存在しているのでその abc ウィンドウの中で目的のリンクが再び開く、という動作をします。 ただし taget="_blank" という指定があった場合のみ例外的に「常に新しいウィンドウを開く」という挙動になります。


一方の(2)は「 JavaScript の処理の一環として新しいウィンドウを指定した属性と URL で開く」という関数を使って実現する方法です。利用者から見た挙動はあまり変わらないのですが、内部的には「ポップアップ」という扱いになり、違いは多くあります:
・ウィンドウサイズが指定できる(わざと小さいウィンドウで開く、といったこともできる)
・スクロールバーやメニュー、アドレスバーの有無などを指定できる
・タブブラウザであっても新しいウィンドウを作って開く
・JavaScript だけで実現できる(ライブラリ化できる)

例えば SDK などの機能をライブラリとして提供する側の立場で新しいウィンドウで何かを表示する、という機能を実現しようとすると、前述の <a> タグを使う方法は(利用者がわざわざ指定どおりの <a> タグを記述しないとできないため)逆に不便だったりします。一方で JavaScript だけでできるこの方法であれば SDK の一部としてその機能を実装しておき、その機能ごと JavaScript ライブラリを提供すればよいので利用者の負担を軽くすることができます(結果的にサポートの負担も減ると思われます)。

といった違いがあって、実装の違いにも現れることになります。


さて、この後者の方法は「ポップアップ」として扱われると書きましたが、このポップアップは特に iOS の Safari ブラウザでは扱いが面倒なものの1つです。具体的にはポップアップ機能自体がデフォルトでオフになっており動きません(つまり上述の window.open で別ウィンドウを開こうとしても開きません)。ここまでは他のブラウザでも同様なのですが、他ブラウザの場合はポップアップをしなかった旨を画面に通知して(そこで利用者は気づくことになって)ポップアップを許可することができ、次回以降の window.open 実行時にポップアップウィンドウが表示できるようになります。しかし iOS の Safari ブラウザではポップアップをしなかったことをユーザーに通知することもないため、ユーザーからすると「何も起こらなかった」ようにしか見えない(エラーメッセージが表示されるわけでもないため、許可すればよいと気づくこともない)のでした。


iOS Safari でポップアップが開くようにするには、あらかじめ Safari アプリケーションの設定でポップアップを許可する(ポップアップブロックを無効にする)必要があります。以下その手順の紹介をします:


iOS Safari でポップアップブロックの設定を変更するには「設定」-「Safari」を選択し、「ポップアップブロック」と書かれた設定項目を探します。過去に一度も変更したことがなければ下図のように「ポップアップブロックは有効(= window.open では新しいウィンドウは開かない)」になっているはずです:
2020031601


ポップアップウィンドウを表示するよう変更したい場合は、この設定を下図のように OFF に切り替えます。設定はこれだけです:
2020031602


この状態で再度 Safari を使って window.open が実行される状態を作ると、まず以下のような確認ウィンドウが表示されます。ここで「許可」をタップすると初めて window.open が実行されて新しいウィンドウが開いて処理を続けることができるようになります:
2020031603



なお、ここで書かれた手順を実行しておくと、先日のブログエントリで紹介した LIFF の新機能を実装したアプリケーションを iOS の Safari からも実行することができるようになります(つまりポップアップを有効にしないと LIFF の shareTargetPicker が動かないようです):
http://dotnsf.blog.jp/archives/1077179113.html


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 ▼" って書かれたいたら(既に展開済みで)ここが展開できるように見えない・・・


(追記おわり)

 

このページのトップヘ