VueでLIFFを動かす

By: Daiki Nimura
Posted: 2020-11-23
TechTypeScript

来週は LINE DEVELOPER DAY が開催されるのでかなりウキウキしている。特に LIFF のこの先の展望とかが気になっている。

LIFF、個人的にはかなり良いと思っているんだけどあまり盛り上がっている印象が無い。リソースとかも基本公式しかないし…(まあ公式読めば大体わかるけど…)

React 業務で書きすぎて飽きたので Vue で動かしていく。

ソースコードも一応貼っておきます。

そもそも LIFF とは?

LINE Front-end Framework の略。詳しくは公式を参照してくだされ。

LINE Front-end Framework

LINE のトーク上で開くブラウザ(LIFF ブラウザ)で Web アプリを動かせて、プロフィール情報の取得やトークへのメッセージ送信などを LIFF Sdk から提供される API を使って行う事が出来る。

普通のブラウザでも機能制限はあるが動く。LINE ログインをバックエンド実装無しで使えたりもするので普通に便利。

LIFF のセットアップ

まずは LINE Developers Console に LINE アカウントでログインする。

新規チャネル作成 →LINE ログインを選択する

https://res.cloudinary.com/dw86z2fnr/image/upload/v1620383437/titanicrising.jp/vue-liff/_2020-11-21_1.08.39_ltuphc.png

項目を入力していく。アプリタイプはウェブアプリを選択する。

LIFF アプリの作成

作成した LINE ログインのチャネル配下にある LIFF タブから入力して作成する。

エンドポイント URL は一旦適当な URL を入れておく。(https で)

https://res.cloudinary.com/dw86z2fnr/image/upload/v1620383437/titanicrising.jp/vue-liff/_2020-11-21_1.11.40_n00iuj.png

作成されて LIFF ID と LIFF URL が見れれば一旦 OK。

どちらもメモっておく。

https://res.cloudinary.com/dw86z2fnr/image/upload/v1620383437/titanicrising.jp/vue-liff/_2020-11-21_1.19.34_cnzbtm.png

Vue のセットアップ

自分で webpack とかチューニングするのめんどいので vue-cli 使う。

vue-cli の設定はマニュアルの TypeScript とか PWA とか全部込みで vue は 3 を使用。composition-api 無しだと Vue の TypeScript 運用は流石に少し厳しいので。

src ディレクトリの中身はこんな感じ。

https://res.cloudinary.com/dw86z2fnr/image/upload/v1620383436/titanicrising.jp/vue-liff/_2020-11-21_1.25.12_vekith.png

簡単なセットアップと LIFF のインストール

まずは環境変数のセット。

プロジェクトルートに.env という名前のファイルを作成。

さっきの LIFF_ID をセットする。

変数名はなんでも良いけど VUE_APP を最初につけなきゃダメらしい。この辺は CRA と似ておりますな。

//.env
VUE_APP_LIFF_ID = 'さっきのLIFF ID'

reset.css とか入れたりしたけどそれらは割愛。

LIFF は npm パッケージが公式から出ているのでインストール。

yarn add @line/liff
or
npm i @line/liff

型定義ファイルも入っているので ts でもそのまま import して使える。

プロフィールを取得してみる

とりあえず src/components/HelloWorld.vue を以下のように編集した。

<template>
  <div class="hello-world" v-if="isInClient">
    <h1 class="hello-world__title">
      Welcome to Your Liff + Vue.js App
    </h1>
    <ul class="hello-world__profile" v-show="liffState.profile">
      <li class="profile-items" v-for="(v, k) in liffState.profile" :key="k">
        <img v-if="k === 'pictureUrl'" :src="v" alt="line-profile-picture" />
        <span v-else>{{ `${k}: ${v}` }}</span>
      </li>
    </ul>
  </div>
  <div
    class="hello-world--loading"
    v-else-if="isInClient === 'NOT_INITIALIZED'"
  >
    Loading...
  </div>
  <div class="hello-world--inactive" v-else-if="isInClient === false">
    Please open in LIFF browser!!
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, reactive, ref } from "vue";
import liff from "@line/liff";

type LiffState = {
  profile?: {
    userId: string;
    displayName: string;
    pictureUrl?: string;
    statusMessage?: string;
  };
};

export default defineComponent({
  setup() {
    const isInClient = ref<boolean | "NOT_INITIALIZED">("NOT_INITIALIZED");
    const liffState = reactive<LiffState>({
      profile: undefined
    });

    const getProfile = async () => {
      const profile = await liff.getProfile();
      liffState.profile = profile;
    };

    onMounted(async () => {
      // LIFFアプリの初期化
      await liff.init({ liffId: process.env.VUE_APP_LIFF_ID });

      // LIFFブラウザで起動しているかの判定
      if (liff.isInClient()) {
        isInClient.value = true;
        getProfile();
        return;
      }

      isInClient.value = false;
    });

    return {
      liffState,
      isInClient
    };
  }
});
</script>

<style lang="scss" scoped>
.hello-world {
  padding-bottom: 60px;

  &--inactive {
    font-size: 1.8rem;
    color: red;
  }

  &__title {
    font-size: 1.8rem;
    font-weight: bold;
    margin-bottom: 20px;
  }

  &__profile {
    font-size: 1.4rem;

    .profile-items {
      padding: 4px 8px;
      > img {
        display: block;
        width: 100%;
      }
    }
  }
}
</style>

細かい LIFF の API の説明とかは公式を見た方が早いので割愛。

まあこのコードはあまりにもやっつけなのでちょっとアレだがしっかり動く。

ngrok を使って実際に動かしてみる

yarn serve して localhost:8080 でみられるようになるが、https しかエンドポイントとして受け付けない LIFF ブラウザで起動するには一工夫必要。ビルド&デプロイしてその URL を使っても良いが開発しながらだと流石にめんどい。ので ngrok を使用する。

以下の記事がわかりやすい。

無事インストールできたら以下のコマンドを叩く。

ngrok http 8080 -host-header="localhost:8080"

http の url と https の url が発行されるはずなので https の方をメモる(ngrok.io で終わるやつ)。

さっきの LINE Developers Console に戻って LIFF の設定を開き、エンドポイント URL にコピペする。

https://res.cloudinary.com/dw86z2fnr/image/upload/v1620383435/titanicrising.jp/vue-liff/_2020-11-21_1.52.38_orhg9u.png

起動!

なんらかの方法でコンソールにある LIFF URL をスマホの LINE のトークで開く。

自分一人の LINE グループ作ってそこに貼るのがおすすめ。

https://res.cloudinary.com/dw86z2fnr/image/upload/v1620383436/titanicrising.jp/vue-liff/IMG_2066_gwdy8x.jpg

開くと認証許可してくれ〜〜って出てくるので許可する。

https://res.cloudinary.com/dw86z2fnr/image/upload/v1620383436/titanicrising.jp/vue-liff/IMG_2067_mzvia4.png

無事 LIFF ブラウザが開き、ロードが終わって(ngrok なので少し時間かかる)プロフィール情報が取れていれば OK!

https://res.cloudinary.com/dw86z2fnr/image/upload/v1620383436/titanicrising.jp/vue-liff/IMG_2067_mzvia4.png

本番環境へのデプロイについて

普通の Vue アプリなので Vercel なり Netlify なり AWS なり Firebase なり好きなところにデプロイして OK。本番環境の LIFF をもう一個作って.env.production にそっちの LIFF_ID をセットしてエンドポイント URL に本番の URL を入れる運用が丸いと思う。

まとめ

LIFF、良いけど DX がダメすぎる。デベロッパーツール使えないしコンソールも見れないし。

まあでもミニアプリと SDK が同じだったり認証早かったりと強みはすごいあるしじわじわ使われていくのではないかと思われる。

出来る事はかなり多いのでアイディア勝負ですな。

Nuxt じゃない Vue 久々に使った。vue-cli めっちゃ進化してて SSR や SSG しないなら Nuxt より全然良いかもね。

人気の記事