LIFF + Nextjs でアプリを作ってわかった「LIFFアプリ」の良さ（宣伝あり）

## 概要

ハッカソンで出たアイディアの中で実装されずに散っていったものを救いたい、、
そういう思いからLIFFアプリを実装することになり、
１週間くらい寝る間を惜しんで、「ノミカイカンジ」というアプリを作りました。。

`ノミカイカンジアカウント`

https://liff.line.me/1645278921-kWRPP32q/?accountId=904siiki

上のリンクはMessaging APIの公式チャネル「ノミカイカンジ」へのリンクであり、
友だち登録することで、LIFFアプリ（ラインをフロントとしてログイン機能などの恩恵を受けられる）
へのリンクを取得できます。

`ノミカイカンジからアクセスできるリンク`

https://liff.line.me/1657643402-X1jYM06L


LIFFアプリを作ったのは初めてだったのですが、今回アプリを作ってみて、結構いいなと思ったので、どこをそう思ったのかということについて書いてみようと思います。


また、上のアプリのプログラムは、あまり大したことはしていないので公開しています。

https://github.com/kenmaro3/nomikai-kanji

`Nextjs + Tailwind + Firebase(Firestore) + LIFF`
という構成に興味がある方がいらっしゃいましたら、参考にしてみてください。


## LIFFアプリの作り方

LIFFアプリは、実装としては基本的にはWebアプリと変わらないと考えてもらっていいです。
チュートリアルでも、Vanilla js, Nextjs, Vuejs などを使ったチュートリアルを実行することができます。

LIFFアプリ構築の手順としては、
LIFFアプリ用のLINEログインチャネルを作成し、Webアプリをデプロイした時のエンドポイントをチャネル内に登録することで構築することができます。

![Screen Shot 2022-11-28 at 21.18.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/de18a2f1-856b-830f-0f89-720f49223265.png)

LINEログインチャネルをLINEディベロッパーに作成した後、LIFFアプリとしてこのチャネルを設定できます。

例えば、NextjsをHerokuやVercel, Netlify などでデプロイした後のエンドポイントを
LIFFアプリ詳細のところで設定できます。

![Screen Shot 2022-11-28 at 21.27.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/d30d97c9-df31-1902-ecc2-cc0e65856c39.png)

この設定をすることで、LIFFアプリにアクセスした際、LINEを経由したログインが発生し、
コールバックとして登録したエンドポイントにアクセスすることができます。

あとは、Nextjsなどを用いて普通にウェブアプリとしてコーディングして、
必要な場所でLINEのAPIを使用し、ログインや、LINEプロフィール情報の取得などを行うようにサービスを構成します。




## LIFF アプリの良さ

これだけいうと、なんだ、ウェブアプリでいいじゃん、と思う方もいると思いますが、
LIFFアプリはLIFFアプリIDを発行し、それを用いるとLINEをフロントとして

- LINEを経由したログイン
- LINEプロフィール（ID)などの情報を取得
- WebアプリからLINEメッセージでの共有を実装できる
- LINEアプリからのLIFFアプリ実行がスムーズである

などの恩恵があります。
私は今回NextJSを用いてLIFFアプリを実装しましたが、
これらの恩恵は結構UXが高いなと思って面白いなと思いましたし、他のアプリも実装してみたいな、
と思ったので、今回はLIFFアプリの良さについて少し書いてみようと思います。

開発をしようと思ったら、実際に

https://developers.line.biz/ja/reference/liff/

こちらの、LIFFアプリのAPIについてのドキュメントを見てみることをお勧めします。



### LINEを経由したログイン

LINEを経由したログインをすることで、Firebaseを用いたログイン実装や、
独自実装したログイン機構を使うことなく、比較的簡単にユーザ認証を行うことができます。
LINEを持っているユーザ（日本であれば大多数の人が持っていると仮定できますし）に対して有効なので、非常にUXが高いなと感じました。

### LINEプロフィール（ID)などの情報を取得
LINEプロフィールの取得については、取り扱いに注意が必要であり、
そこは公式のドキュメントに書かれているサービス構成図をきちんと理解する必要があります。

しかしながら、LIFFアプリから得られる情報は極めて限定的であり、ユーザのプライバシーを考慮して実装すれば問題はないと思われます。
LINEプロフィール名やID、プロフィール画像へのリンクなどにアクセスできるため、
LIFFアプリ上にそれらの情報を出すことで、ユーザがわざわざプロフィールをウェブアプリのために設定する必要もないですし、LINEを見ているような感覚でアプリを操作することができます。
これについてもアプリ開発者側からしてもUXが高いなと思いました。


### WebアプリからLINEメッセージでの共有を実装できる
LINEのAPIを用いることで、LIFFアプリを経由して、ユーザの友達（ユーザが自分で選択する）に対して、
LIFFアプリがカスタマイズしたメッセージを共有することができます。
これは結構便利だと思いました。実際私の作ったアプリでも、飲み会を幹事が設定して、グループラインにお知らせ、投票を行なってもらう際に、ボタン１つでグループラインに対して招待リンクを送信することができ、ユーザの手間を減らすことができたな、と感じました。
このようなユーザの操作ステップが１つでも減る工夫ができるという意味で、UXが高いなと思いました。

### LINEアプリからのLIFFアプリ実行がスムーズである
先ほどのLIFFアプリにエンドポイントを登録する画面で、
「サイズ」という項目がありましたが、この項目で、LINEからLIFFアプリを開いた時のモーダルの大きさを指定できます。

これにより、LINEの画面全体を覆うような立ち上がり方であったり、半分を覆うような実装にもできるため、
例えばユーザが半分はLINEの画面を見ながら（例えばLINE Messaging チャネルの情報を見ながら）LIFFアプリをいじることができるため、とても便利だと思いました。

以上が私がLIFFアプリいいなあと思った事柄でした。


せっかくなので、LIFFアプリならではのLINE経由のログインや、
LINEでのメッセージ共有の実装部分を少しだけ解説して終わりにしたいと思います。


### LINE経由でのログイン

https://github.com/kenmaro3/nomikai-kanji/blob/main/pages/_app.js

こちらをみていただくと、

```_app.js
  useEffect(() => {
    // to avoid `window is not defined` error
    import("@line/liff").then((liff) => {
      liff
        .init({ liffId: process.env.NEXT_PUBLIC_LIFF_ID })
        .then(() => {

          if (!liff.isLoggedIn()) {
            liff.login();
          }
        })
        .catch((error) => {
          console.log(`liff.init() failed: ${error}`);
          if (!process.env.liffId) {
            console.info(
              "LIFF Starter: Please make sure that you provided `LIFF_ID` as an environmental variable."
            );
          }
        });
    });
  }, []);
```

この`UseEffect`内でログインを実行しています。


### LINEメッセージでの共有

https://github.com/kenmaro3/nomikai-kanji/blob/main/pages/nomi/confirm.js

このファイルの、

```confirm.js
  const sendMessageViaTargetPicker = () => {
    import("@line/liff").then((liff) => {
      if (liff.ready) {
        if (liff.isApiAvailable("shareTargetPicker")) {
          liff.shareTargetPicker(
            [
              {
                type: "text",
                text: `ノミカイカンジでノミタイカンジ。\nカンジからのご連絡です🍺\n飲み会の開催を計画しています。`,
              },
              {
                type: "text",
                text: `こちらからリンクにアクセスして投票してください。 \n${shareUrl} \nアクセスの際には次のメッセージに記載のパスコードを入力してください。`,
              },
              {
                type: "text",
                text: `${passcode}`,
              },
            ],
            {
              isMultiple: true,
            }
          )
            .then(function (res) {
              if (res) {
                // succeeded in sending a message through TargetPicker
              } else {
                const [majorVer, minorVer] = (liff.getLineVersion() || "").split('.');
                if (parseInt(majorVer) == 10 && parseInt(minorVer) < 11) {
                  // LINE 10.3.0 - 10.10.0
                  // Old LINE will access here regardless of user's action
                } else {
                  // LINE 10.11.0 -
                  // sending message canceled
                  console.log('TargetPicker was closed!')
                }
              }
            }).catch(function (error) {
              // something went wrong before sending a message
              console.log('something wrong happen')
            })
        } else {
          console.log("api not available")
        }
      } else {
        console.log("liff is not ready")
      }
    });
  }
```

この箇所でLINEメッセージを介した情報共有を実装しています。



## まとめ

今回は、`Nextjs + Tailwind + Firebase(Firestore) + LIFF`
を使ってLIFFアプリを作った時に感じた、LIFFアプリのいいところ

について書いてみました。

LIFFアプリは基本的にはウェブアプリを構築して、
LIFFアプリとしてインターフェースをLINEにしたければ、後から少し編集して登録することも可能です。
UXは基本的に上がると思うので、個人開発などの選択肢として考えているのは大いにありだと思います。


LINEをインターフェースにできるので、ユーザとしては開きやすく、親しみやすいアプリにしやすいような気がしています。

今度は、Vueを使ってLIFFアプリ作りにもチャレンジしてみたいと思っています。


みなさんもよいLIFFアプリライフを。



今回はこの辺で。

@kenmaro