🤳🏽

LIFFでQRコードリーダーを作ってみた(liff.scanCodeV2()を使って)

2021/12/24に公開

LINE DCAdvent Calendarもついに最終日です!

最終日は2本立てで書きました。

もう一本はNode-REDで実装するLINE Payを使ったbotを紹介しているので、そちらもよかったらぜひご覧ください。

https://zenn.dev/kmiura55/articles/line-pay-bot

LIFFv2にはQRコードリーダーが使えるAPIがかつて存在していました。

が、技術的な問題がありiOSでは基本的に使えなくなり、Androidも一部機種でしか対応しない状態になりました。

https://developers.line.biz/ja/news/2019/11/29/liff-functions-suspended/

なので、LIFFでQRコードを使いたい人たちは代替方法でなんとか実装していたんじゃないかなと思います。

しかし! 今年の9月に発表されたv2.15.0ではそのQRコードリーダーが技術的問題を解消して復活しました‼

https://twitter.com/k_miura_io/status/1444277227961536513

リリース記事にもありますが、v2.15.0で追加された liff.scanCodeV2()の特徴は内部でJavaScriptのライブラリを使用しています。

つまり、 iOS、Androidといったネイティブだけではなく、ブラウザでも使えるということなんです!

本当はリリースしてすぐ試そうとしましたが、なかなか時間が取れずアドベントカレンダーの季節になったので、今回はこの新しいQRコードリーダーを使ったLIFFアプリをVue.jsで作っていきたいと思います。

Vue.jsじゃないとだめなわけではなく、今年から使い始めたZennで最初に投稿したのがVue.jsを使ったLIFFアプリなので、今年のシメもVue.jsを使ってみたかっただけですw。

https://zenn.dev/kmiura55/articles/6524c0f7e21183

今回作るもの

LIFFのQRコードリーダーで読み込んだ値をアプリ上に表示されるシンプルなアプリです。

ソースコードは以下のGithubレポジトリで公開しています。

https://github.com/Miura55/liff_qr

開発環境

  • Node.js: v16.0.0
  • Vue CLI: 4.5.13
  • LIFF: v2.15.0

環境構築

Vue.js のプロジェクトを作成

以下のコマンドで Vue.js のプロジェクトを作成します。

vue create liff_qr

プリセットの選択が出るので、Default (Vue 3 Preview) ([Vue 3] babel, eslint)を選択します。

LIFF パッケージのインストール

続いて LIFF の npm パッケージを用意します。

以下のコマンドでインストールします。

npm install @line/liff@2.15.0

ngrok の用意

ngrok を用意して以下のコマンドでホスティングを起動します。

ngrok http 8080

実行後に生成した URL は次の設定で必要なので、メモしておきます。(https のほうを選択します。)

LIFF ID の用意

次に LIFF ID を用意します。

LINE Developersにログインし、プロバイダーを作成したらチャネルの作成から「LINE ログイン」を選択します。

LIFFタブから LIFF を作成します。

サイズの項目は必ず Fullにする必要があります。でないとLINEアプリ上でLIFFを起動したときにQRコードリーダーが起動しません。(僕もTallに設定してつまりました…)

エンドポイント URL には先程メモした ngrok の URL を記入します。

また Scope は profile にチェックを入れます。

そして、忘れてはいけないのが Scan QR Code をオンにしておくことです。そうすることでQRコードが起動できるようになります。

必要なファイルの用意

App.vue

まずはApp.vueを作成します。

src/App.vueを以下のコードに書き換えます。

src/App.vue
<template>
  <h1 v-if="!isLoggedIn">ログインします</h1>
  <div v-if="isLoggedIn">
    <img alt="LINE Profile" width="100" height="100" :src="profileImg" />
    <h1>Hello, {{ userName }}</h1>
    <p class="text-width" v-if="scanMsg">読み取ったテキスト: {{ scanMsg }}</p>
    <button class="btn-square" @click="scanQR">読み取り</button>
  </div>
</template>

<script>
import liff from "@line/liff";

export default {
  name: "App",
  data() {
    return {
      isLoggedIn: false,
      profileImg: undefined,
      userName: undefined,
      scanMsg: "",
    };
  },
  created() {
    liff
      .init({
        liffId: process.env.VUE_APP_LIFF_ID,
        withLoginOnExternalBrowser: true,
      })
      .then(() => {
        this.isLoggedIn = liff.isLoggedIn();
        if (this.isLoggedIn) {
          liff.getProfile().then((profile) => {
            this.userName = profile.displayName;
            this.profileImg = profile.pictureUrl;
          });
        }
      });
  },
  methods: {
    scanQR: function () {
      liff
        .scanCodeV2()
        .then((result) => {
          this.scanMsg = result.value;
        })
        .catch((err) => {
          console.log(err);
        });
    },
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.text-width {
  width: 100%;
}
.btn-square {
  display: inline-block;
  padding: 0.5em 1em;
  text-decoration: none;
  background: #42b983;
  color: #fff;
  border-bottom: solid 4px #627295;
  border-radius: 3px;
}
.btn-square:active {
  -webkit-transform: translateY(4px);
  transform: translateY(4px);
  border-bottom: none;
}
</style>

さてサラッとコードを書きましたが、LIFFを実装したことある方ならこのコードに違和感を感じるかもしれません。

そう、今回のアプリはネイティブ、ブラウザ両方に対応している必要があるのに liff.login()が1つも入っていません。

なぜなら liff.init()withLoginOnExternalBrowsertrueにしたことでliff.init()のときに liff.login() が自動で呼んでくれるからです。

実はこのプロパティも v2.15.0で追加された新機能です!

https://developers.line.biz/ja/news/2021/09/30/release-liff-2-15-0/#liff-init-auto-login-2021-09-30

これでブラウザで使うLIFFアプリの実装で毎回 liff.login()を記述する必要がなくなるのでコードが少しスッキリすると思います。

.env

続いて、.env を作成します。

.envをアプリのルートディレクトリに新規作成して以下の内容を記入します。YOUR_LIFF_IDはご自分のものに書き換えます。

VUE_APP_LIFF_ID="YOUR_LIFF_ID"

vue.config.js

最後に、vue.config.js を作成します。これはローカルで立ち上げたVueアプリをngrok経由で開こうとしたときに Invalid Host header というエラーが出るのを防ぐために必要です。

vue.config.jsをアプリのルートディレクトリに新規作成して以下の内容を記入します。

vue.config.js
module.exports = {
  devServer: {
    disableHostCheck: true,
  },
};

動作確認

それでは、Vueアプリを立ち上げて動作確認しましょう。

以下のコマンドでサーバーを立ち上げます。

npm run serve

作成したLIFF URLにアクセスして以下の動画のように 読み取り ボタンを押してQRコードリーダーが起動し、読み取った値が表示されれば動作確認は成功です。

ブラウザの場合は 読み取りボタンを押したときに再度ログインをするとQRコードリーダーが立ち上がるはずです。

https://twitter.com/k_miura_io/status/1474025367061024772

まとめ

今回はv2.15.0で追加された新しいQRコードリーダーを使ったLIFFアプリを紹介しました。

そして、同じくv2.15.0で追加された liff.init() した時に liff.login() が自動で呼ばれる実装も取り入れたことで気がついたら今年新たに追加された新機能を試すサンプルコードにもなってましたw。

QRコードリーダーがLIFFの標準機能として復活しただけではなく、さらにブラウザでもつかえるようにしたのもかなり大きいのではないかと思います。

あとは超個人的にはLINE Thingsもこの調子で復活してくれるといいなと思ってたりしてます。

まぁ可能性はないかもしれませんが来年に期待しましょうw。

というわけで、皆さんよいお年を!

Discussion