React + TypeScriptを使ってLIFFを作る
Tags: react, line, typescript, liff
Published: 2020-08-26 12:33:44

---
title: React + TypeScriptを使ってLIFFを作る
published: true
tags: React,LINE,TypeScript,LIFF
//cover_image: https://direct_url_to_image.jpg
---

Reactjs + TypeScriptでLIFFアプリを試したときのメモです。

コードは以下のリポジトリにあります。

{% github YutaGoto/liff-sample %}

## LIFFとは

https://developers.line.biz/ja/docs/liff/overview/

> LINE Front-end Framework（LIFF）は、LINEが提供するウェブアプリのプラットフォームです。このプラットフォームで動作するウェブアプリを、LIFFアプリと呼びます。

## 環境

```plain
node: v14.5.0
npx: 6.4.1
npm: 6.14.6
yarn: 1.22.4
```

バージョンを揃えなくとも動くと思います。

## React Appをつくる

https://ja.reactjs.org/tutorial/tutorial.html#setup-option-2-local-development-environment
https://create-react-app.dev/docs/adding-typescript/

ReactjsのチュートリアルにあるとおりReactAppを生成するコマンドを実行する
今回はTypeScriptを使用するのでオプションに追加しておきます。

```sh
npx create-react-app liff-sample --template typescript
```

一通り生成できたら動作するかどうかを確認します。

```sh
cd liff-sample
yarn start
```

`http://localhost:3000` にアクセスして以下のようなページが表示されたらOK。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ko327lwx72lzy5ef181c.png)

## LIFFのセットアップ

### チャネルの準備

https://developers.line.biz/console/ にアクセスします。

プロバイダーがなければ、新規でプロバイダーを作成します。[LINE DEV](https://developers.line.biz/ja/docs/liff/getting-started/)の記事を確認しながら進めてください。

プロバイダーができたらそれを選択し、新規チャネルを作成します。このときのチャネルの種類は `LINEログイン` を選択します。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6h7z0qoxbqhr33g5b4pj.png)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ahvokdd2g3o4wzny074h.png)

選択したら必須項目を入力する。アプリタイプは `ウェブアプリ` を選択します。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/y3n9ndy68xc0asnqhk0s.png)

### LIFFの準備

チャネルを作成し終えたらLIFFのページから追加をクリックしてLIFFを作成します。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/01pktlzkv0tlzagkh2uv.png)

**LIFFアプリを追加**のページになったら必要な情報を入力します。ローカル環境でLIFFを試すときは ngrok などを駆使します。

https://ngrok.com/

Scopeは必要なほうを選択します。（LINEログインをがっつり使うとかなければ Profileのみでよいと思います）
LIFFからメッセージを送信する必要があるときは **すべてを表示** をクリックして展開して **message.write** にもチェックを付けます。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wtvh25c54p26z6893uff.png)

LIFFを作成したら LIFF IDをLIFF URLが生成されたのを確認します。
このIDやURLはあとで使用します。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9lvelcyeyg216svt5cdy.png)

## ReactAppに埋め込む

### ライブラリインストール

LINE公式のnpmパッケージがあるので追加しておきます。

https://www.npmjs.com/package/@line/liff

```sh
yarn add @line/liff
```

### コードの編集

`App.tsx` を編集します。

```tsx
import React from 'react';
import liff from '@line/liff'; // 追加
import logo from './logo.svg';
import './App.css';

function App() {
  /* 追加: メッセージ送信 */
  const sendMessage = () => {
    liff.init({liffId: process.env.REACT_APP_LIFF_ID as string}) // LIFF IDをセットする
      .then(() => {
        if (!liff.isLoggedIn()) {
          liff.login({}) // ログインしていなければ最初にログインする
        } else if (liff.isInClient()) { // LIFFので動いているのであれば
          liff.sendMessages([{ // メッセージを送信する
            'type': 'text',
            'text': "You've successfully sent a message! Hooray!"
          }]).then(function() {
            window.alert('Message sent');
          }).catch(function(error) {
            window.alert('Error sending message: ' + error);
          });
        }
      })
  }

  /* 追加: UserProfileをAlertで表示 */
  const getUserInfo = () => {
    liff.init({liffId: process.env.REACT_APP_LIFF_ID as string})
      .then(() => {
        if (!liff.isLoggedIn()) {
          liff.login({}) // ログインしていなければ最初にログインする
        } else if (liff.isInClient()) {
          liff.getProfile()  // ユーザ情報を取得する
            .then(profile => {
              const userId: string = profile.userId
              const displayName: string = profile.displayName
              alert(`Name: ${displayName}, userId: ${userId}`)
            }).catch(function(error) {
              window.alert('Error sending message: ' + error);
            });
        }
      })

  }

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <button className="button" onClick={sendMessage}>send message</button> // 追加
        <button className="button" onClick={getUserInfo}>show user info</button> // 追加
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
```

上記のコード編集とCSSの編集し再度アクセスすると以下のようになるはずです。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ty5tw7co0qc70kdv2sfj.png)

PCブラウザではLIFFではないのでボタンをクリックしてもなにも反応がないはずです。(エラーにはなります)

liffの詳しいAPIリファレンスはLINE公式のものを参照してください。

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

## LINE上でLIFFを試す。

ローカルのngrokで試す場合は環境変数(上記コードで言う `REACT_APP_LIFF_ID` )に値をセットします。
どこかのサーバにデプロイするときであっても同様です。
vercelを使用するとかなり手軽にデプロイできて試せます。

https://vercel.com

環境変数などがセット完了し、サーバデプロイなどが終わったら LIFF URLをてきとーなトークルームに送信します。ひとりだけのトークルームを使うと誰にも迷惑をかけずに試せます。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5bnveccwj3ti0pwopz97.png)


このリンクをタップしたらLIFFが立ち上がるはずです。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ntw6qty30orifmg5ya7h.png)

 `send message` をタップすると、最初にもろもろ許可してOKかどうかのページが表示されます。

許可したあとにもう一度 `send message` をタップすると、そのトークルームにメッセージが送信されます。

`show user info` をタップすると、自身のユーザ名とユーザIDが表示されます。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/206edfarulymkvs5ziqv.jpg)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ipf5wqliinqiqihskbpk.png)

ここまでできたら、あとはいろいろAPIを試してみたりするだけです。