LoginSignup
22
16

More than 3 years have passed since last update.

Vue.js + TypeScriptで作るLIFF v2アプリ

Last updated at Posted at 2020-07-01

2020/07/02追記

記事を公開した当日に公式のnpmパッケージが公開されました。
https://developers.line.biz/ja/news/2020/07/01/published-liff-npm-package/

上記パッケージを使用することでLIFF SDKの導入と同時に型の情報を得ることが出来るので、本記事の内容よりそちらを推奨します。

はじめに

まず、LIFFとはLINEが提供するウェブアプリのプラットフォームです。現在の最新バージョンは2系となっており、LIFF v2と表記されます。
以下は概要の引用ですが、LIFFを使用することでLINEの機能を活かしたWebアプリを開発することが出来ます。
https://developers.line.biz/ja/docs/liff/overview/

LINE Front-end Framework(LIFF)は、LINEが提供するウェブアプリのプラットフォームです。このプラットフォームで動作するウェブアプリを、LIFFアプリと呼びます。
LIFFアプリを使うと、LINEのユーザーIDなどをLINEプラットフォームから取得できます。LIFFアプリではこれらを利用して、ユーザー情報を活用した機能を提供したり、ユーザーの代わりにメッセージを送信したりできます。

本記事ではLIFFアプリをVue.js + TypeScriptで作成します。

手順

本記事では以下の手順でLIFFアプリを作成します。

  1. チャネルを作成する
  2. Vue.jsのプロジェクトを作成する
  3. LIFFアプリを開発する

1.の手順は主に LINE Developers 上の話を、2.の手順では Vue CLI でVue.jsのプロジェクトを作成する話をします。
上記手順は読み飛ばしても大丈夫という方は3.のLIFFアプリを開発する部分だけをお読みいただけると幸いです。

チャネルを作成する

ngrokを起動

LIFFアプリを作成するためにはWebアプリをhttpsで公開する必要があります。
S3などにホスティングしても良いのですが、本記事ではngrokを使用してローカルで動くVue.jsアプリを公開します。
※ngrokのセットアップは主題から外れるため割愛します。

ngrok http 8080

image.png

https://xxx.ngrok.ioはLIFFのエンドポイントURLとして使用するので控えておきます。

プロバイダーを作成する

  1. LINE Developersにログインする
  2. プロバイダーを作成する

image.png

チャネルを作成する

作成したプロバイダーにLINEログインチャネルを追加します。

image.png

LIFFアプリを追加する

チャネルにLIFFアプリを追加します。

image.png

各設定項目については公式のドキュメントに詳しく書かれています。
エンドポイントURLには前述の手順で控えておいたngrokのURL、https://xxx.ngrok.ioを指定します。

ここまでの手順で以下のようなLIFFアプリが作れているかと思います。

image.png

LIFF ID はアプリ開発時に必要になります。ユーザーは LIFF URL にアクセスすることでこのLIFFアプリを開くことが出来ます。

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

プロジェクトの作成

本記事ではVue CLIを使用してプロジェクトを作成します。
(プロジェクト名は適宜置き換えてください)

vue create liff-app

プロジェクトの設定は任意のもので構いませんが、本記事では以下のような設定で作成しています。

image.png

ngrokからアクセスできるようにする

以下の設定をpackage.jsonに追加します。

package.json
  "vue": {
    "devServer": {
      "disableHostCheck": true
    }
  }

動作確認

以下のコマンドでVue.jsアプリを起動し、https://xxx.ngrok.ioからアクセスできることを確認します。

npm run serve

ngrok経由でVue.jsアプリを開ければ、LIFFアプリとして実行することが出来ます。
前項の手順で作成したLIFF URL、https://liff.line.me/xxxにアクセスすると以下のように表示されると思います。

image.png

LIFFアプリを開発する

LIFF SDKを組み込む

LINE SDKはCDN経由でのみ配布されています。以下のscriptタグをindex.htmlに追加します。

index.html
<script charset="utf-8" src="https://static.line-scdn.net/liff/edge/2/sdk.js"></script>

この状態でLIFF SDKは使用可能な状態となりますが、せっかくTypeScriptで使用するので型の情報が欲しくなります。
幸運なことにliff-typeという素晴らしいパッケージが公開されているのでこちらを使用します。

ドキュメントにある通り以下のコマンドでインストールし、

npm i -D liff-type

tsconfig.jsonファイルに以下の内容を追記します。
※追記内容は環境に応じて適宜読み替えてください

tsconfig.json
{
  "compilerOptions": {
    "types": ["liff-type"]
  }
}

正しく設定が行えればインテリセンスが利いた快適なLIFFアプリ開発環境が作れると思います。
image.png

LIFFアプリを初期化する

LIFF SDKの機能を使用するためには、はじめにliff.init()を実行する必要があります。
作法として正しいのかは分かりませんが、今はアプリ全体でliffの機能を使用したいためApp.vuecreatedのタイミングで実行する処理を入れてみます。

なお、liff.initの実行にはLIFF IDが必要となります。

App.vue
@Component
export default class App extends Vue {
  @Prop({ type: Boolean, default: false })
  loggedIn = false;

  created() {
    liff.init({
      liffId: 'ここにLIFF IDを入れる'
    })
    .then(() => {
      this.loggedIn = liff.isLoggedIn();
    })
  }
}

LIFFアプリが動作している環境を取得する

<template>
  <div class="liff-data">
    <table>
      <tr>
        <th>OS</th>
        <td>{{ os }}</td>
      </tr>
      <tr>
        <th>Language</th>
        <td>{{ language }}</td>
      </tr>
      <tr>
        <th>LIFF SDK Version</th>
        <td>{{ sdkVersion }}</td>
      </tr>
      <tr>
        <th>LINE Version</th>
        <td>{{ lineVersion }}</td>
      </tr>
      <tr>
        <th>isInClient</th>
        <td>{{ isInClient }}</td>
      </tr>
      <tr>
        <th>isLoggedIn</th>
        <td>{{ isLoggedIn }}</td>
      </tr>
    </table>
  </div>
</template>

<script>
import { Component, Vue } from "vue-property-decorator";

@Component
export default class LiffData extends Vue {
  get os() {
    return liff.getOS();
  }

  get language() {
    return liff.getLanguage();
  }

  get lineVersion() {
    return liff.getLineVersion();
  }

  get sdkVersion() {
    return liff.getVersion();
  }

  get isInClient() {
    return liff.isInClient();
  }

  get isLoggedIn() {
    return liff.isLoggedIn();
  }
}
</script>

ユーザのプロフィールを取得する

<template>
  <div class="profile">
    <table>
      <tr>
        <th>IDトークンの生成URL</th>
        <td>{{ token.iss }}</td>
      </tr>
      <tr>
        <th>ユーザーID</th>
        <td>{{ token.sub }}</td>
      </tr>
      <tr>
        <th>チャネルID</th>
        <td>{{ token.aud }}</td>
      </tr>
      <tr>
        <th>トークンの有効期限</th>
        <td>{{ token.exp }}</td>
      </tr>
      <tr>
        <th>IDトークンの生成時間</th>
        <td>{{ token.iat }}</td>
      </tr>
      <tr>
        <th>ユーザー認証時間</th>
        <td>{{ token.auth_time }}</td>
      </tr>
      <tr>
        <th>nonce</th>
        <td>{{ token.nonce }}</td>
      </tr>
      <tr>
        <th>認証方法</th>
        <td>{{ token.amr }}</td>
      </tr>
      <tr>
        <th>表示名</th>
        <td>{{ token.name }}</td>
      </tr>
      <tr>
        <th>プロフィールの画像URL</th>
        <td>{{ token.picture }}</td>
      </tr>
      <tr>
        <th>メールアドレス</th>
        <td>{{ token.email }}</td>
      </tr>
    </table>
  </div>
</template>

<script>
import { Component, Vue } from "vue-property-decorator";

@Component
export default class Profile extends Vue {
  get token() {
    return liff.getDecodedIDToken();
  }
}
</script>

QRコードリーダを表示する

2020/07/01現在、QRコードリーダーの表示はiOS版LINEバージョン9.19.0以降では動作しないため、関数が存在するかを確認してから使用する必要があります。

参考:https://developers.line.biz/ja/docs/liff/developing-liff-apps/#opening-qr-code-reader

<template>
  <div class="qr">
    {{ scanText }}
    <button v-on:click="qrScan">
      <span>QRコード読み取り</span>
    </button>
  </div>
</template>

<script>
import { Component, Vue } from "vue-property-decorator";

@Component
export default class QR extends Vue {
  scanText = "";

  qrScan() {
    if (liff.scanCode) {
      liff.scanCode().then(result => {
        const stringifiedResult = JSON.stringify(result);
        this.scanText = stringifiedResult;
      });
    }
  }
}
</script>

メッセージを送信する

2020/07/01現在、LIFFアプリからメッセージを送信する方法は現在のトークに送信する方法とターゲットピッカーを表示して、ユーザが選んだ相手に送信する方法の2種類存在します。
後者のターゲットを選択する方法はLINE 10.3.0以降でサポートされる機能のため、動作環境で使用可能かを確認してから送信します。

<template>
  <div class="message">
    <input v-model="message" />
    <button v-on:click="sendMessage">
      <span>送信</span>
    </button>
  </div>
</template>

<script>
import { Component, Vue } from "vue-property-decorator";

@Component
export default class Message extends Vue {

  message = 'LIFFへようこそ!';

  sendMessage() {
    liff.sendMessages([{
      'type': 'text',
      'text': this.message
    }]).then(function() {
      window.alert('Message sent');
    }).catch(function(error) {
      window.alert('Error sending message: ' + error);
    });
  }
}
</script>
22
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
16