LoginSignup
9
11

More than 3 years have passed since last update.

【LINE】LIFFアプリを試してみる~ユーザ情報の取得とトークへの送信~

Last updated at Posted at 2020-03-21

概要

  • LIFFを使ってLINEのユーザ情報の取得とLINEへのメッセージ投稿を試してみます
  • 前回書いたセットアップが完了している前提で進めます
  • 公式のスターターは特にフレームワークを使っていませんが今回は私が使い慣れたReactで試してみます

Reactアプリの雛形生成

  • create-react-appでさくっと作成します
npx create-react-app liff-sample

LIFF SDKのセットアップ

  • LIFF SDKはnpmからインストールする形式では提供されていないので使いやすいように一手間入れておきます
  • public/index.htmlにLIFF SDKの読み込み処理を追加
    • しれっとそれ以外も手を加えてますがそのままでも影響ありません
public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>LIFF App</title>
  </head>
  <body>
    <div id="root"></div>
    <!-- LIFF SDKの読み込みを追加  -->
    <script src="https://static.line-scdn.net/liff/edge/2.1/sdk.js"></script>
  </body>
</html>
  • グローバルに定義されたliffをexportするファイルを追加
    • そのままグローバルなliffを使ってもいいですがimportして使えるようにします
  • src/lib/liff.jsを作成
src/lib/liff.js
export const liff = window.liff;
  • これでimport { liff } from './lib/liff'のような形でimportできるようになりました

LIFF APIへのアクセス処理を追加

実装

  • まずはliffのinitialize処理を書きます
  • 使いやすいようにCustomHooks化してしまいます
  • src/hooks/useLiff.jsを作成します
    • initLiffメソッドがちょっと長いですが例外処理を書いているだけでtryの中に注目してください
src/hooks/useLiff.js
import { useState, useEffect } from 'react';
import { liff } from '../lib/liff';

function useLiff({ liffId }) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const initLiff = async ({ liffId }) => {
    setLoading(true);
    try {
      // LIFF APIのinitを呼び出して初期化
      await liff.init({ liffId });
      alert('success liff init');
    } catch (error) {
      alert({ error });
      setError(error);
    } finally {
      setLoading(false);
    }
  };

  // useLiffが呼ばれたらinitialize処理を実行する
  useEffect(() => {
    initLiff({ liffId });
  }, [liffId]);

  return { loading, error };
}

export default useLiff;
  • useLiffをReactアプリのエントリーポイントであるsrc/App.jsに適用します
src/App.js
import React from 'react';
import useLiff from './hooks/useLiff';

// LIFF IDを設定(後述)
const liffId = '1234567890-abcedfgh';

function App() {
  const { loading, error } = useLiff({ liffId });

  if (loading) return <p>...loading</p>;
  if (error) return <p>{error.message}</p>;

  return (
    <div>
      <h1>Hello LIFF</h1>
    </div>
  );
}

export default App;
  • LIFF IDはURLスキームの値です
    • line://app/1234567890-abcedfgh1234567890-abcedfghの部分
    • 環境変数で埋め込んでもよいですが説明の簡略化のためここでは直接書いてしまいます

動作確認

  • いったんここまでで動きを確認してみます
  • 確認するためにはhttpsの環境にデプロイする必要があるのでお好きなホスティングサービスにデプロイしてください
    • NowNetlifyであれば無料であっという間にデプロイできます
  • デプロイできたらLINE DeveloperのWebコンソールでURLを設定します
    • 前回の記事で暫定でQiitaのURLを設定してたやつを差し替えます
  • LIFFの設定までたどって「エンドポイントURL」を変更します

スクリーンショット 2020-03-22 3.52.48.png

  • 設定を反映できたらLINEからアクセスしてみましょう
  • うまくいけば動画のようにinitがsuccessするはずです

init.gif

ユーザ情報の取得

実装

  • ログインまで確認できたので次はユーザ情報を取得してみます
  • src/hooks/useLiff.jsに処理を追加します
src/hooks/useLiff.js
import { useState, useEffect } from 'react';
import { liff } from '../lib/liff';

function useLiff({ liffId }) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  // 追加
  const [profile, setProfile] = useState(null);

  const initLiff = async ({ liffId }) => {
    // 省略
  };

  // 追加
  const fetchProfile = async () => {
    setLoading(true);
    try {
      // LIFF APIのgetProfileを実行し結果をセット
      setProfile(await liff.getProfile());
    } catch (error) {
      console.log({ error });
      setError(error);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    initLiff({ liffId });
  }, [liffId]);

  // 修正
  return { loading, error, fetchProfile, profile };
}

export default useLiff;
  • src/App.jsに適用します
    • ボタンを押すと通信処理が走り情報を取得します
    • 取得できる情報は以下の4つです
      • ユーザID
      • 表示名
      • プロフィール画像のURL
      • ステータスメッセージ(設定されてなければ何も返されない)
    • 今回は画面に出しておしまいですがユーザIDをサーバに送ってキー情報として使うイメージですね
src/App.js
import React from 'react';
import useLiff from './hooks/useLiff';

// 自身のLIFF IDを設定
const liffId = '1234567890-abcedfgh';

function App() {
  // 修正
  const { loading, error, profile, fetchProfile } = useLiff({ liffId });

  if (loading) return <p>...loading</p>;
  if (error) return <p>{error.message}</p>;

  return (
    <div>
      <h1>Hello LIFF</h1>
      {/* 追加 */}
      <section>
        {/* ボタンをクリックしたらfetchProfileを実行 */}
        <button onClick={() => fetchProfile()}>Get Profile</button>
        {/* 取得したProfileを表示 */}
        {profile && (
          <div>
            <p>UserID: {profile.userId}</p>
            <p>DisplayName: {profile.displayName}</p>
            <p>
              Picture: <br />
              <img src={profile.pictureUrl} height="300" width="300" />
            </p>
            {profile.statusMessage && <p>StatusMessage: {profile.statusMessage}</p>}
          </div>
        )}
      </section>
    </div>
  );
}

export default App;

動作確認

  • ここまでできたらデプロイして取得できることを確認します
  • うまくいけば取得した情報が表示されるはずです

profile.gif

メッセージの送信

実装

  • 最後にLINEのトークへのメッセージの送信を実装します
  • src/hooks/useLiff.jsに関数を追加します
src/hooks/useLiff.js
import { useState, useEffect } from 'react';
import { liff } from '../lib/liff';

function useLiff({ liffId }) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [profile, setProfile] = useState(null);

  const initLiff = async ({ liffId }) => {
    // 省略
  };

  const fetchProfile = async () => {
    // 省略
  };

  // 送信する内容を引数で受け取る
  const sendMessage = async ({ text }) => {
    setLoading(true);
    try {
      // LIFF APIのsendMessagesを実行
      liff.sendMessages([{ type: 'text', text }]);
      console.log(`success send message: ${text}`);
    } catch (error) {
      console.log({ error });
      setError(error);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    initLiff({ liffId });
  }, [liffId]);

  // 修正
  return { loading, error, fetchProfile, profile, sendMessage };
}

export default useLiff;
  • src/App.jsに適用します
  • 送信内容入力するフォームも合わせて設置しておきます
src/App.js
// useStateを追加
import React, { useState } from 'react';
import useLiff from './hooks/useLiff';

// 自身のLIFF IDを設定
const liffId = '1234567890-abcedfgh';

function App() {
  // 修正
  const { loading, error, profile, fetchProfile, sendMessage } = useLiff({ liffId });
  // メッセージのstateを追加
  const [text, setText] = useState('');

  if (loading) return <p>...loading</p>;
  if (error) return <p>{error.message}</p>;

  return (
    <div>
      <h1>Hello LIFF</h1>
      <section>
        <button onClick={() => fetchProfile()}>Get Profile</button>
        {profile && (
          <div>
            <p>UserID: {profile.userId}</p>
            <p>DisplayName: {profile.displayName}</p>
            <p>
              Picture: <br />
              <img src={profile.pictureUrl} height="300" width="300" />
            </p>
            {profile.statusMessage && (
              <p>StatusMessage: {profile.statusMessage}</p>
            )}
          </div>
        )}
      </section>
      {/* メッセージの入力域と送信ボタンを追加 */}
      <section>
        <input onChange={e => setText(e.target.value)} />
        <button onClick={() => sendMessage({ text })}>Send</button>
      </section>
    </div>
  );
}

export default App;

動作確認

  • 再度デプロイして試してみますよう
  • うまくいけばメッセージが送信されているはずです!

send.gif

まとめ

  • 今回はLIFFアプリを作ってユーザ情報の取得とトークへのメッセージ送信を実装しました
  • この2つができればLIFFの恩恵は受けられそうですね
  • どんなユースケースで活用できそうか考えてみようと思います

コード

9
11
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
9
11