LoginSignup
8
4

More than 1 year has passed since last update.

LIFF Mockを使ってみた

Posted at

はじめに

LIFF InspectorとLIFF Mockをリリースされたとのことで。ローカルでのテストが楽になりそうなLIFF Mockを早速使ってみることにします。

やってみる

サンプルコードとしてこちらも最近リリースされたcreate-liff-appを使います。まずはプロジェクトの作成。設定は好みで。

npx @line/create-liff-app
Need to install the following packages:
  @line/create-liff-app
Ok to proceed? (y) y
Welcome to the Create LIFF App
? Enter your project name:  (my-app) my-app
? Which template do you want to use? react
? JavaScript or TypeScript? TypeScript
? Please enter your LIFF ID: xxxxxx
? Do you want to install it now with package manager? (Y/n) Yes
? Which package manager do you want to use? yarn

あとでMock化するのでLIFF IDは適当にxxxxxxとしておきました

@line/liff-mockを追加します

cd my-app
yarn add @line/liff-mock

開発環境を起動します

yarn dev

スクリーンショット 2022-05-03 16.14.59.png

http://localhost:3000/にアクセスするとサンプルアプリが表示されます。存在しないLIFF IDを設定したためliff.ini()が失敗しています

src/App.tsxを以下のように更新してLIFF Mock pluginを追加します

src/App.tsx
import { useEffect, useState } from "react";
import liff from "@line/liff";
import "./App.css";
import { LiffMockPlugin } from '@line/liff-mock';

liff.use(new LiffMockPlugin());

function App() {
  const [message, setMessage] = useState("");
  const [error, setError] = useState("");

  useEffect(() => {
    liff
      .init({
        liffId: import.meta.env.VITE_LIFF_ID,
        mock: true, // enable mock mode
      })
      .then(() => {
        setMessage("LIFF init succeeded.");
      })
      .catch((e: Error) => {
        setMessage("LIFF init failed.");
        setError(`${e}`);
      });
  });

  return (
    <div className="App">
      <h1>create-liff-app</h1>
      {message && <p>{message}</p>}
      {error && (
        <p>
          <code>{error}</code>
        </p>
      )}
      <a
        href="https://developers.line.biz/ja/docs/liff/"
        target="_blank"
        rel="noreferrer"
      >
        LIFF Documentation
      </a>
    </div>
  );
}

export default App;

npm-typescript-exampleを参考にtypes/liff.d.tsを追加します。TypeScriptの場合この型定義がないと型エラーが発生します

types/liff.d.ts
import { ExtendedInit, LiffMockApi } from '@line/liff-mock';

declare module '@line/liff' {
  interface Liff {
    init: ExtendedInit;
    $mock: LiffMockApi;
  }
}

LIFF Mockを追加するとliff.init()が成功するようになりました。うまくMock化できたようです。

スクリーンショット 2022-05-03 19.13.15.png

Mock化されたliff.getProifle()を呼んでみます。取得したプロファイルはsetMessage()を拝借して表示してみます

App.tsx
import { useEffect, useState } from "react";
import liff from "@line/liff";
import "./App.css";
import { LiffMockPlugin } from '@line/liff-mock';

liff.use(new LiffMockPlugin());

function App() {
  const [message, setMessage] = useState<string>("");
  const [error, setError] = useState("");

  useEffect(() => {
    const f = async () => {
      const options = {
        liffId: import.meta.env.VITE_LIFF_ID,
        mock: true, // enable mock mode
      };
      try {
        await liff.init(options);
        if (!liff.isLoggedIn()) {
          liff.login();
          const profile = await liff.getProfile();
          setMessage(JSON.stringify(profile));
        }
      } catch (e) {
        setMessage("LIFF init failed.");
        setError(`${e}`);
      }
    };
    f();
  });

  return (
    <div className="App">
      <h1>create-liff-app</h1>
      {message && <p>{message}</p>}
      {error && (
        <p>
          <code>{error}</code>
        </p>
      )}
      <a
        href="https://developers.line.biz/ja/docs/liff/"
        target="_blank"
        rel="noreferrer"
      >
        LIFF Documentation
      </a>
    </div>
  );
}

export default App;

実行するとダミーのプロファイルが取得できました

スクリーンショット 2022-05-03 19.47.25.png

おもしろいので他のメソッドもモック化されているのか試してみました。scanCodeV2()を呼んでみます

src/App.tsx
      try {
        await liff.init(options);
        if (!liff.isLoggedIn()) {
          liff.login();
          const scaned = await liff.scanCodeV2();
          setMessage(JSON.stringify(scaned));
        }
      } catch (e) {
        setMessage("LIFF init failed.");
        setError(`${e}`);
      }

スクリーンショット 2022-05-03 19.50.42.png

QRコードのスキャン結果としてhttps://line.meが返ってきました

liff.sendMessages()もエラーなく正常に実行されました

src/App.tsx
      try {
        await liff.init(options);
        if (!liff.isLoggedIn()) {
          liff.login();
          await liff.sendMessages([ { type: "text", text: "Hello, World!", } ]);
          setMessage('Message sent');
        }
      } catch (e) {
        setMessage("LIFF init failed.");
        setError(`${e}`);
      }

スクリーンショット 2022-05-03 20.04.12.png

liff.$mock.set()を利用してMock APIが返すデータを設定することができます

src/App.tsx
import { useEffect, useState } from "react";
import liff from "@line/liff";
import "./App.css";
import { LiffMockPlugin } from '@line/liff-mock';

liff.use(new LiffMockPlugin());

liff.$mock.set((p) => ({
  ...p,
  getProfile: { displayName: 'bathtimefish', userId: '123456789' },
}));

function App() {
  const [message, setMessage] = useState<string>("");
  const [error, setError] = useState("");

  useEffect(() => {
    const f = async () => {
      const options = {
        liffId: import.meta.env.VITE_LIFF_ID,
        mock: true, // enable mock mode
      };
      try {
        await liff.init(options);
        if (!liff.isLoggedIn()) {
          liff.login();
          const profile = await liff.getProfile();
          setMessage(JSON.stringify(profile));
        }
      } catch (e) {
        setMessage("LIFF init failed.");
        setError(`${e}`);
      }
    };
    f();
  });

  return (
    <div className="App">
      <h1>create-liff-app</h1>
      {message && <p>{message}</p>}
      {error && (
        <p>
          <code>{error}</code>
        </p>
      )}
      <a
        href="https://developers.line.biz/ja/docs/liff/"
        target="_blank"
        rel="noreferrer"
      >
        LIFF Documentation
      </a>
    </div>
  );
}

export default App;

スクリーンショット 2022-05-03 19.56.50.png

liff.$mock.clear()liff.$mock.set()で設定したデータをデフォルト値に戻します

src/App.tsx

liff.$mock.set((p) => ({
  ...p,
  getProfile: { displayName: 'bathtimefish', userId: '123456789' },
}));

....

        await liff.init(options);
        if (!liff.isLoggedIn()) {
          liff.login();
          liff.$mock.clear();
          const profile = await liff.getProfile();
          // {"displayName":"Brown","userId":"123456789","statusMessage":"hello"}
          setMessage(JSON.stringify(profile));
        }

現時点でLIFF MockのAPIは以上です

おわりに

ローカルでLIFFアプリを開発する場合は一部のAPIがローカルで正常に動作しないのを回避するために工夫する必要がありました。LIFF Mockプラグインを使うことでその苦労がなくなります。個人的にはプロトタイピングする前にチャンネルを作ったりLIFF IDやLIFF URLを生成したりする手間がなくLIFF APIを試せるのが気持ちよくなったところです。

これからLIFFアプリを開発しようとする方はcreate-liff-appとLIFF Mockを利用してカジュアルにLIFF APIを試してみるところからはじめるといいんじゃないでしょうか。

8
4
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
8
4